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

标签 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。我怎样才能做到这一点?一般问题是如何删除输出中根本未修改的那些行。

最佳答案

一般方法

虽然下面包含了大写字母的特殊情况解决方案,但一般来说,我们可能需要所有单独的 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 是打印更改行的显式命令。

关于linux - 使用具有多个替换命令的脚本时控制 sed 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25828071/

相关文章:

linux - Ubuntu 无法挂载 Windows 硬盘驱动器,即使 Windows 在双启动时正确关闭

linux - SH Linux : Syntax error: word unexpected

bash - 如何在执行过程中从/usr/bin/time输出到正确位置的文件?

linux - Bash 是默认的,但当我运行“bash : in terminal?”时仍然会发生变化

linux - Xrandr 检测到但不连接 HDMI

php - 使用sed从php文件中删除注释

bash - Mercurial:检查最后一次拉取/更新是否引入了更改

linux - 如何从第二行使用 awk '{print $1*Number}' 或告诉他忽略 NaN 值?

linux - Grep Only 返回第一个匹配结果(不需要)。我该如何防止这种情况?

c - 如何告诉 gcc 停止使用内置函数?