2012-03-22 27 views
0

私はちょっと前にスーパーユーザーにthis questionを投稿しましたが、私は好きな答えを得ていません。ここは少し修正されています。Sedは交換線全体を置き換えます

私は、交換(だけでなく試合)で行全体を置き換えるsedを作るための方法を期待していたので、私はこのような何か行うことができます:

sed -e "/$some_complex_regex_with_a_backref/\1/" 

をし、それが唯一のバックを印刷してい参照。

投稿者:this questionこれは、正規表現を使って行全体を一致させる方法や、perlのような他のツールを使用する方法のようです。 regex.*regex.*に変更するだけでは、(その質問に記載されているように)常に機能するとは限りません。たとえば:

$ echo $regex 
\([:alpha:]*\)day 

$ echo "$phrase" 
it is Saturday tomorrow 
Warm outside... 

$ echo "$phrase" | sed "s/$regex/\1/" 
it is Satur tomorrow 
Warm outside... 

$ echo "$phrase" | sed "s/.*$regex.*/\1/" 

Warm outside... 

$ # what I'd like to have happen 
$ echo "$phrase" | [[[some command or string of commands]]] 
Satur 
Warm outside... 

私は次のことを想定し、行全体(だけではなく、一致する部分)を交換するための最も簡潔な方法を探しています:

  • 正規表現は変数であり、そうすることができます場合によっては変更することはできません。私はPerlや他の言語ドッシリ使用せずにこれを実行したい
  • (など、けれども、sed、awk、grepのはOKです)
  • ソリューションは、元の正規表現に一致しない行を削除することはできません(すみませんgrep -oそれをカットしません)。

私が考える何だったの以下の(しかし、それは醜いですので、私はより良いものがあるかどうかを知りたいのですが):

$ sentinel=XXX 
$ echo "$phrase" | sed "s/$regex/$sentinel\1$sentinel/" | 
> sed "s/^.*$sentinel\(.*\)$sentinel.*$/\1/" 

答えて

2

これはあなたのために働くかもしれない:

sed '/'"$regex"'/!b;s//\n\1\n/;s/.*\n\(.*\)\n.*/\1/' file 
+0

それは動作します!どのようにそれを簡単に説明するケア? – jakesandlund

+0

'\ n'は* sentinel *と表示されます。 sedは '\ n'を行区切り文字として使用するので、' \ n'はユーザーが挿入しない限りパターンスペースに現れません。したがって、理想的なセンチネル*です。 – potong

関連する問題