![组合两个不带管道的命令(awk 和 sed)](https://linux22.com/image/106040/%E7%BB%84%E5%90%88%E4%B8%A4%E4%B8%AA%E4%B8%8D%E5%B8%A6%E7%AE%A1%E9%81%93%E7%9A%84%E5%91%BD%E4%BB%A4%EF%BC%88awk%20%E5%92%8C%20sed%EF%BC%89.png)
我有一个使用 awk 和 sed 的命令。
awk '{$1=""; print $0}' file.txt | sed "1s/.*/D,,3/" #awk command removes first column from file.txt and prints the rest, sed inserts "D,,3" on the first line
我得到了上述命令所需的结果。但是,我试图避免使用管道,有没有一种方法可以组合上面的两个命令并在不使用管道的情况下获得相同的结果。
first : awk '{$1=""; print $0}' file.txt
second: sed "1s/.*/D,,3/"
file.txt:
row 3:
name john doe
state Florida
age 32
答案1
awk 和 sed 都是图灵完备,所以无论一个人能做什么,另一个人也能做。 (就文本转换而言,即 awk 具有更多的操作系统交互设施。)但是,每个都有自己的优点和缺点。 awk 可以轻松完成 sed 的大部分功能,但有一些事情(例如用组替换正则表达式)更加困难。理论上,sed 可以做 awk 可以做的任何事情,但有相当大的困难(例如 sed 没有整数运算,因此您必须使用文本转换对其进行编码)。因此,如果您想将所有内容都放在一个命令中,awk 通常是您的最佳选择。
awk 'NR==1 {print "D,,3"; next} {$1=""; print $0}' file.txt
在这里,sed 还可以轻松地完成您使用 awk 所做的事情:规范化空白并将所有内容剪切到第一个空格。
sed "s/[ \t][ \t]*/ /g; s/^ *[^ ][^ ]*/ /; s/^ $//; 1s/.*/D,,3/" file.txt
在这里,将这两个命令结合起来并不是特别有用。我预计不会有性能提升。每个管道都会有性能损失,因为数据必须从一个命令流向下一个命令。但是,也可以有性能提升。如果您有多个 CPU,那么这两个命令可以并行执行。如果对某些事情使用更专业的命令(例如,使用专用工具(如grep
和)head
而不是通用工具(如 awk),那么更专业的命令通常更快。增益是否补偿管道的开销取决于数据、工具、您拥有的核心数等。
除非这个脚本是性能瓶颈,否则首先要考虑清晰度。在这种情况下,我会避免使用纯 sed 版本 - 它可能会稍微快一点,但可读性要差很多。 (在对数据的某些假设下,它可能会被简化,例如,如果您知道总是至少有两个字段并且字段分隔符始终是单个空格,或者您不关心保留空格数量。)我发现在 awk 中做所有事情都更清晰,但它与 awk+sed 版本之间有接近的平局。