Bash:处理I/O最有效的方法是什么?
Bash: what is the most efficient way to handle I/O?
我有一个 bash 脚本,它可以进行大量的字符串操作。据我所知,从文件中读取很慢。因此,我没有在每次需要它的内容时都这样做,而是在脚本的开头阅读了整个文件
readarray -t lines < "$filename"
但每次我需要将行输入到接受输入的程序(例如,awk
、cut
、grep
)时,我无论如何都必须打印它们并创建一条管道。这是一个在文件中找到包含冒号的第一行的示例
line=$(printf -- '%s\n' "${lines[@]}" | grep -n -m 1 :)
所以我开始怀疑,我不是只是通过额外调用 echo
并创建管道来让它变慢吗?处理这种情况的最佳方法是什么?
您可以使用 bash-特定的 <<<
运算符将变量通过管道传输到命令中,而无需 echo
/printf
-ing 它们:
λ printf "test\nline\n" > file
λ cat file
test
line
λ readarray -t lines < file
λ wc -c <<< "${lines[0]}"
5
λ printf "%s" "${lines[0]}"
test
此外,假设您不需要一次需要所有内容,您可以直接使用类似这样的东西来使用它,而不是将文件读入变量:
while read -r line; do
grep -n -m1 ':' <<< "$line" && {
echo "Got colon"
break
}
done < filename
如果你想看哪个更快,可以试试time
:
time readarray -t lines < "$filename"
time line=$(printf -- '%s\n' "${lines[@]}" | grep -n -m 1 :)
这会给你以毫秒为单位的时间,让你看看哪个更快。
我有一个 bash 脚本,它可以进行大量的字符串操作。据我所知,从文件中读取很慢。因此,我没有在每次需要它的内容时都这样做,而是在脚本的开头阅读了整个文件
readarray -t lines < "$filename"
但每次我需要将行输入到接受输入的程序(例如,awk
、cut
、grep
)时,我无论如何都必须打印它们并创建一条管道。这是一个在文件中找到包含冒号的第一行的示例
line=$(printf -- '%s\n' "${lines[@]}" | grep -n -m 1 :)
所以我开始怀疑,我不是只是通过额外调用 echo
并创建管道来让它变慢吗?处理这种情况的最佳方法是什么?
您可以使用 bash-特定的 <<<
运算符将变量通过管道传输到命令中,而无需 echo
/printf
-ing 它们:
λ printf "test\nline\n" > file
λ cat file
test
line
λ readarray -t lines < file
λ wc -c <<< "${lines[0]}"
5
λ printf "%s" "${lines[0]}"
test
此外,假设您不需要一次需要所有内容,您可以直接使用类似这样的东西来使用它,而不是将文件读入变量:
while read -r line; do
grep -n -m1 ':' <<< "$line" && {
echo "Got colon"
break
}
done < filename
如果你想看哪个更快,可以试试time
:
time readarray -t lines < "$filename"
time line=$(printf -- '%s\n' "${lines[@]}" | grep -n -m 1 :)
这会给你以毫秒为单位的时间,让你看看哪个更快。