如何通过一个表达式用一个单词搜索和替换多根针?


8

假设您有一个文本文件:

foo fnord bar
bizz foo poit

现在,我想将“ foo”和“ bar”都替换为“ narf”。

我知道我可以使用:

 sed -e 's/foo/narf/g' -e 's/bar/narf/g' fileName

但是,我想使用一个OR运算符,该运算符告诉正则表达式通过一个表达式匹配两个指针。

我打了一些手册,我认为管子应该符合我的需求,但是我尝试了

sed -e 's/foo|bar/narf/g' -i fileName

它没有用,甚至没有抛出错误。

我在这里做错了什么?

Answers:


10

使用-r扩展正则表达式语法的选项:

sed -r -e 's/foo|bar/narf/g'

否则逃脱析取为\|

sed -e 's/foo\|bar/narf/g'

6

正则表达式语法有很多变体。Unix世界中最早具有正则表达式的工具并不具有正则表达式的全部功能,只有字符集([…].),重复(*)和行锚(^$)。基本正则表达式只有这些运算符。Sed是一种老式工具,使用基本的正则表达式。

许多sed实现都有完整的正则表达式匹配的扩展。由于字符|代表本身,你需要使用\|的交替,同样\(\)进行分组。请注意,POSIX标准并不要求基本正则表达式\|必须支持它,而某些系统(例如OpenBSD)则没有。

某些版本的sed可以选择切换到扩展的正则表达式(…)用于分组和|交替。使用GNU sed(即在Linux或Cygwin下)或Busybox时,传递该-r选项。在FreeBSDOSX上,传递-E选项。

如果您的sed没有交替,您可以致电awk。它是由POSIX强制执行的,但是对于此任务有点冗长,并且不支持反向引用。

awk '{gsub(/foo|bar/, "narf")}' <fileName.old >fileName.new

顺便说一下,只有GNU和Busybox sed支持替换文件。Awk和其他版本的sed则没有。请参阅我可以使`cut`改变文件位置吗?

如果您有Perl,则通常以一种工具完成所有形式的单行工具就很方便。在sed,awk中最容易实现的大多数事情,在Perl中并不困难,而您可以通过学习单个(如果是复杂的)工具来摆脱困境。

perl -i -pe 's/foo|bar/narf/g' fileName

0

您可以在Ex模式下使用Vim:

ex -sc '%s/\vPA|QU/RO/g|x' file
  1. % 选择所有行

  2. s 替代

  3. \v 打开魔术

  4. g 全球替代

  5. x 保存并关闭

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.