2013-09-27 8 views
6

*シンボルのテキスト中の重複する単語をすべて強調表示する必要があります。それは私を与えるsedで同じ行に何度もコマンドを実行

echo "lol foo lol bar foo bar" | sed -r -e 's/(\b[a-zA-Z]+\b)([^*]+)(\1)/\1\2*\3*/' 

lol foo lol bar foo bar 

例えば
は、私は、次のコマンドを使用してみました

lol foo *lol* bar *foo* *bar* 

でなければなりません

lol foo *lol* bar foo bar 

それから私は、を追加しましたフラグ:

lol foo *lol* bar foo *bar* 

しかしfooがハイライトされていません。
私はそれが起こることを知っていますseddoesn't look behind if the match was found

sedで処理することはできますか?

+1

あなたは 'sed'と言うだけです...これは私が信じるいくつかの' sed'ウィザードを必要とします。 – rid

+0

なぜ 'awk'を使わないのですか?あなたの問題を解決するかもしれません。 – Jotne

+0

@Jotne率直に言って、私はsedだけでそれをするという仕事をしています。しかし、一般的に私は 'sed'が同じコマンドを複数回実行できるのであれば興味があった – Dany

答えて

4

Sedは、このタスクに最適なツールではありません。それは、先読みを見て背後に、見て、非貪欲数量が、次のコマンドを試してみていません:

sed -r -e ':a ; s/\b([a-zA-Z]+)\b(.*) (\1)(|$)/\1\2 *\3*/; ta' 

それが失敗するまでの置換コマンドを実行する条件分岐を使用しています。また、([^*]+)を確認することはできません。第2ラウンドでは、最初の置換の*をトラバースする必要があるため、選択肢はグリーディ.*です。最後に、(\1)と一致することはできません。なぜなら、最初の文字列lolが何度も繰り返されるからです。スペースや行末に囲まれたようなコンテキストが必要です。

コマンド収量:

lol foo *lol* bar *foo* *bar* 

UPDATE:コメントでpotongによって提供される改善:使用

sed -r ':a;s/\b(([[:alpha:]]+)\s.*\s)\2\b/\1*\2*/;ta' file 
+0

+1素晴らしい...それは魔法です! – iamauser

+0

@Bireiはい、これは魔法です、それは私のために働く! この場合、 'a'と' ta'コマンドが何をするのか説明してください。 – Dany

+0

最後の単語が繰り返しであるときに、この解決策が行末に余分なスペースを導入する可能性があるため、少し改善があります: 'sed -r ':a; s/\ b(([[:alpha:]] +)\ s。* \ s)\ 2 \ b/\ 1 * \ 2 * /; ta 'file'。 N.B. 'ta'コマンドの直前に' l0'コマンドを挿入すると、sedがその魔法をするのを見ることができます。 – potong

1

awk

awk '{for (i=1;i<=NF;i++) if (a[$i]++>=1) printf "*%s* ",$i; else printf "%s ",$i; print ""}' file 
lol foo *lol* bar *foo* *bar* 
関連する問題