k0p*_*kus 8 sed search text-processing regular-expression
假设您有一个文本文件:
foo fnord bar
bizz foo poit
Run Code Online (Sandbox Code Playgroud)
现在我想将“foo”和“bar”都替换为“narf”。
我知道我可以使用:
sed -e 's/foo/narf/g' -e 's/bar/narf/g' fileName
Run Code Online (Sandbox Code Playgroud)
然而,我想与一个 OR 运算符一起工作,它告诉正则表达式通过一个表达式匹配两个针。
打了一些手册,我想管道应该适合我的需要,但我试过了
sed -e 's/foo|bar/narf/g' -i fileName
Run Code Online (Sandbox Code Playgroud)
它没有用,它甚至没有抛出错误。
我在这里做错了什么?
Sté*_*nez 10
使用-r扩展正则表达式语法的选项:
sed -r -e 's/foo|bar/narf/g'
Run Code Online (Sandbox Code Playgroud)
否则逃避析取为\|:
sed -e 's/foo\|bar/narf/g'
Run Code Online (Sandbox Code Playgroud)
正则表达式语法有很多变体。Unix 世界中第一个具有正则表达式的工具并不具备正则表达式的全部功能,只有字符集([…]和.)、重复(*)和线锚(^和$)。基本的正则表达式只有这些运算符。Sed 是一个老式的工具,使用基本的正则表达式。
许多 sed 实现都有完整的正则表达式匹配的扩展。因为字符|代表它自己,所以你需要使用\|交替,类似地\(,\)用于分组。请注意,POSIX 标准并未强制要求\|在基本正则表达式中支持,并且某些系统(例如OpenBSD)没有它。
某些版本的 sed 可以选择切换到扩展正则表达式,(…)用于分组和|交替。使用 GNU sed(即在 Linux 或 Cygwin 下)或Busybox,传递-r选项。在FreeBSD或OSX 上,传递-E选项。
如果您的 sed 没有交替,您可以awk改为调用。它由POSIX强制要求,但对于此任务来说有点冗长,并且它不支持反向引用。
awk '{gsub(/foo|bar/, "narf")}' <fileName.old >fileName.new
Run Code Online (Sandbox Code Playgroud)
顺便说一下,只有 GNU 和 Busybox sed 支持文件替换。awk 和其他版本的 sed 没有。请参阅我可以让 `cut` 就地更改文件吗?
如果您有 Perl,它通常可以以一种工具一应俱全的方式方便地处理单行文本。大多数在 sed、awk 中容易的东西在 Perl 中并不难,你可以通过学习一个(如果复杂)工具来逃脱。
perl -i -pe 's/foo|bar/narf/g' fileName
Run Code Online (Sandbox Code Playgroud)