使用带有多个替换命令的脚本时控制sed输出

时间:2014-09-13 21:51:24

标签: linux bash shell sed scripting

我有这个:

$ cat sedscr 
s/a/A/
s/c/C/
s/n/N/

$ cat file3
#: another
#: bbc
nanco
hello
another

当我这样做时,我得到如下所示的输出:

$ sed -f sedscr file3
#: ANother
#: bbC
NAnCo
hello
ANother

我不希望输出中有hello。我怎样才能做到这一点?一般性问题是如何删除输出中未完全修改的那些行。

2 个答案:

答案 0 :(得分:3)

一般方法

虽然下面列出了用于大写字母的特殊情况解决方案,但一般来说,我们可能需要所有单独的s语句。这个解决方案(由Jonathan Leffler改进)展示了如何做到这一点:

$ sed 's/a/A/; s/c/C/; s/n/N/; t; d' file3
#: ANother
#: bbC
NAnCo
ANother

注意:

  • s/a/A/; s/c/C/; s/n/N/;

    这是替换

  • t

    如果上述任何替换导致更改的行,则测试命令t将跳转到脚本的末尾,此时将打印修改后的行。

    对于那些好奇的人,如果我们使用了多个t命令,那么如果自脚本中的最后一个t命令(每个周期/行)以来有任何替换,则每个t命令都会跳转。对于更复杂的情况,t命令接受标签作为参数,并跳转到该标签。

  • d

    如果没有进行跳转,那么下一个要执行的命令是d(删除)。这将删除该行,并且不打印任何内容。

对于MacOSX:

sed -e 's/a/A/' -e 's/c/C/' -e 's/n/N/' -e t -e d file3

资本化一些信件的特例

这会将a,n或c转换为大写,并仅在进行更改时打印该行:

$ sed -nr 's/([anc])/\U\1/p' file3
#: Another
#: bbC
Nanco
Another

\U是GNU扩展。

注意:

  • -n告诉sed除非我们明确要求,否则不要打印行。

  • -r要求扩展正则表达式语法,因此我们不需要这么多反斜杠。在Mac OSX上,请改用-E

  • s/([anc])/\U\1/p

    这使得第一个a,n或c的替换成为大写。最后的p是打印更改行的显式命令。

答案 1 :(得分:0)

这可能适合你(GNU sed):

sed '/[acn]/!d;y/acn/ACN/' file

如果不满足第一个条件,则删除该行,否则使用translate命令。

或者如果您愿意:

sed -n '/[anc]/{s/a/A/;s/c/C/;s/n/N/;p}' file