2012-03-22 183 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