sed 和 awk 是否提供了我无法在带有普通 bash 的 bash 脚本中轻松完成的任何事情?

the*_*ian 1 bash sed awk shell-script

我在学习 sed 和 awk 之前学习了 bash。我看到人们使用 sed、awk,有时甚至是 grep 的许多事情,我似乎只能使用 bash 逻辑。我想知道sed 和 awk 有哪些用例可以使它们作为已经是 bash 脚本编写者的人学习有用?如果不完全了解 sed 和 awk,这很难确定。

ter*_*don 9

这有点像询问如果您已经知道如何用手和膝盖爬行,那么学习如何驾驶汽车是否有任何意义。是的,bash 可能会被滥用于一些基本的文本操作或简单的数学运算,但它是最慢的工具,语法很复杂,而且很容易出错。此外,包括 bash 在内的 shell 无法进行浮点运算,这极大地限制了您仅使用 shell 所能实现的目标。

这些原因中的任何一个就足够了,但这里有一个非常简单的例子。拿一个比 1 到 100,000 的数字随机排列更复杂的文件:

seq 100000 | shuf > file
Run Code Online (Sandbox Code Playgroud)

现在,让我们选择所有奇数。在 bash 中,您可以执行以下操作:

$ time while read num; do [[ $num =~ [24680]$ ]] || echo $num; done < file > newfile

real    0m3.481s
user    0m2.648s
sys     0m0.801s
Run Code Online (Sandbox Code Playgroud)

在我的机器上花了大约 3 秒钟。如果我们做同样的事情,但数字在 1 到 1,000,000 之间怎么办?

seq 1000000 | shuf > file
Run Code Online (Sandbox Code Playgroud)

和:

$ time while read num; do [[ $num =~ [24680]$ ]] || echo $num; done < file > newfile

real    0m32.483s
user    0m25.035s
sys     0m7.343s
Run Code Online (Sandbox Code Playgroud)

已经超过30秒了!现在,比较相同的东西awk可以做适当的数学运算:

$ time awk '$1 % 2 !=0' file > newfile 

real    0m0.344s
user    0m0.340s
sys     0m0.003s
Run Code Online (Sandbox Code Playgroud)

不到一秒钟。sed 怎么样,使用相同的文本匹配方法/

$ time sed -n '/[13579]$/p' file > newfile 

real    0m0.280s
user    0m0.273s
sys     0m0.007s
Run Code Online (Sandbox Code Playgroud)

不到一秒,又一次。那么如果我们增加到 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

Run Code Online (Sandbox Code Playgroud)

如您所见,shell 解决方案比非 shell 解决方案慢几个数量级。而一个 1000 万行的文件也不是什么特别稀罕的事情。这只是一个 76M 的文本文件。此外,两种非外壳解决方案都更短(就字符长度而言),并且一旦您了解了它们的语法,就会简单得多。

所以,这是一个“当你只有一把锤子,一切看起来都像钉子”的情况。是的,bash 可以做一些你可以用工具做的事情,比如sed或者awk但它慢得多,而且不擅长工作。