更有效的方法来循环shell中的行

时间:2017-05-04 17:07:43

标签: bash performance shell loops

我来学习通过

循环遍历bash中的行
while read line; do stuff; done <file

不是最有效的方法。 https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice

什么是更有时间/资源效率的方法?

4 个答案:

答案 0 :(得分:0)

正如其他人所说,这取决于你正在做什么。

效率低下的原因是一切都在自己的过程中运行。取决于你在做什么,这可能是也可能不是什么大问题。

如果您想在循环中执行的操作是另一个shell进程,那么您将无法从消除循环中获得任何收益。如果你可以在不需要循环的情况下完成所需的工作,那么你可以获得收益。

答案 1 :(得分:0)

AWK? Perl的? C(++)?当然,这取决于你是否对CPU时间或程序员时间感兴趣,后者取决于程序员习惯使用的内容。

您链接的问题的最佳答案几乎解释了最大的问题是产生简单文本处理任务的外部流程。例如。为每一行运行zipfile.ZipFile的实例或awksed的管道只是为了获取字符串的一部分是愚蠢的。

如果你想留在shell中,请尽可能多地使用字符串处理parameter expansionscut${var#word}${var:n:m}等)和其他shell功能。如果您发现自己为每个输入行运行了一组命令,那么就该再次考虑脚本的结构了。大多数文本处理命令可以通过一次执行来处理整个文件,因此请使用它。

一个琐碎/愚蠢的例子:

${var/search/replace}

会更好

while read -r line; do
    x=$(echo "$line" | awk '{print $2}')
    somecmd "$x"
done < file

答案 2 :(得分:0)

这是使用Bash和awk的time示例。我在一个文件中有100万条记录:

$ wc -l 1M
1000000 1M

使用while read

计算bash的记录
$ time while read -r line ; do ((i++)) ; done < 1M ; echo $i

real    0m12.440s
user    0m11.548s
sys     0m0.884s
1000000

使用let "i++"花了15.627秒(真实)和NOPing与do : ; 10.466。使用awk:

$ time awk '{i++}END{print i}' 1M
1000000

real    0m0.128s
user    0m0.128s
sys     0m0.000s

答案 3 :(得分:0)

选择function escapeRegExp(str) { return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } awk两者都有效

awk or perl