我在学习 sed 和 awk 之前先学了 bash。我看到人们使用 sed、awk、有时甚至 grep 来完成很多事情,但我似乎只能使用 bash 逻辑来完成。我在想sed 和 awk 的哪些用例对于已经是 bash 脚本编写者的学习来说很有用?如果不完全了解 sed 和 awk,则很难确定这一点。
答案1
这有点像问如果你已经知道如何用手和膝盖爬行,那么学习如何驾驶汽车是否还有意义。是的,bash 可以被滥用于一些基本的文本操作或简单的数学,但它是最慢的工具,语法很复杂,而且非常非常容易出错。此外,包括 bash 在内的 shell 无法进行浮点运算,这极大地限制了仅使用 shell 所能实现的功能。
这些原因中的任何一个就足够了,但这里有一个非常简单的例子。取一个文件,该文件只不过是将 1 到 100,000 的数字按随机顺序打乱:
seq 100000 | shuf > file
现在,让我们选择所有奇数。在 bash 中,你可以这样做:
$ time while read num; do [[ $num =~ [24680]$ ]] || echo $num; done < file > newfile
real 0m3.481s
user 0m2.648s
sys 0m0.801s
在我的机器上大约需要 3 秒。如果我们做同样的事情,但数字在 1 到 1,000,000 之间怎么办?
seq 1000000 | shuf > file
和:
$ time while read num; do [[ $num =~ [24680]$ ]] || echo $num; done < file > newfile
real 0m32.483s
user 0m25.035s
sys 0m7.343s
这已经超过30秒了!现在,比较一下awk
可以进行正确数学运算的相同事物:
$ time awk '$1 % 2 !=0' file > newfile
real 0m0.344s
user 0m0.340s
sys 0m0.003s
不到一秒钟。 sed 怎么样,使用相同的文本匹配方法/
$ time sed -n '/[13579]$/p' file > newfile
real 0m0.280s
user 0m0.273s
sys 0m0.007s
不到一秒,又是一次。那么如果我们增加到 10,000,000 又如何呢?
$ seq 1000000 | shuf > file
$ time awk '$1 % 2 !=0' file > newfile
real 0m4.081s
user 0m3.896s
sys 0m0.090s
$ time sed -n '/[13579]$/p' file > newfile
real 0m2.898s
user 0m2.683s
sys 0m0.111s
$ time while read num; do [[ $num =~ [24680]$ ]] || echo $num; done < file > newfile1
real 5m42.445s
user 4m25.687s
sys 1m15.241s
正如您所看到的,shell 解决方案比非 shell 解决方案慢几个数量级。而一个1000万行的文件并不是什么特别罕见的事情。这只是一个76M的文本文件。此外,两种非 shell 解决方案都短得多(就字符长度而言),并且一旦您了解了它们的语法,就会简单得多。
所以,这就是“当你只有一把锤子时,一切看起来都像钉子”的情况。是的,bash 可以做一些你可以使用sed
或 之类的工具做的事情,awk
但它速度慢得多,而且做得不太好。