2012-03-22 173 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 2012-03-22 21:14:39

+0

你在哪裏看到'\ n'讀* sentinel *。由於sed使用'\ n'作爲行分隔符,'\ n'不能出現在模式空間中,除非它被用戶插入。因此它是理想的哨兵*。 – potong 2012-03-22 22:03:57