Bash 将文件内容导入程序的有效方法
假设我们有命令Bash 将文件内容导入程序的有效方法,bash,piping,Bash,Piping,假设我们有命令cmd,它只通过管道接收输入。给定一个文件名file.txt,将其导入命令的最有效方法是什么?(我假设cat file.txt | cmd不是很有效。)让我们用一个1 GB的blob(dump.data)做一个小测试: 使用操作员比使用cat中的管道快得多: $ time cat dump.data | cat >/dev/null real 0m0.360s user 0m0.000s sys 0m0.608s $ time cat <dump
cmd
,它只通过管道接收输入。给定一个文件名file.txt
,将其导入命令的最有效方法是什么?(我假设cat file.txt | cmd
不是很有效。)让我们用一个1 GB的blob(dump.data
)做一个小测试:
使用
操作员比使用cat
中的管道快得多:
$ time cat dump.data | cat >/dev/null
real 0m0.360s
user 0m0.000s
sys 0m0.608s
$ time cat <dump.data >/dev/null
real 0m0.158s
user 0m0.000s
sys 0m0.156s
让我们用一个1GB的blob(
dump.data
)做一个小测试:
使用
操作员比使用cat
中的管道快得多:
$ time cat dump.data | cat >/dev/null
real 0m0.360s
user 0m0.000s
sys 0m0.608s
$ time cat <dump.data >/dev/null
real 0m0.158s
user 0m0.000s
sys 0m0.156s
下面是一些其他计时结果
fn="file.txt"
[[ -e $fn ]] && rm "$fn"
for i in {1..100} ; do
echo "Line $i" >> "$fn"
done
arg='{print FNR, $0}'
N=1000
func1() {
for i in $(seq 1 $N) ; do
awk "$arg" "$fn" > "$temp_file"
done
}
func2() {
for i in $(seq 1 $N) ; do
cat "$fn" | awk "$arg" > "$temp_file"
done
}
func3() {
for i in $(seq 1 $N) ; do
while read line ; do
printf "%s\n" "$line"
done <"$fn" | awk "$arg" > "$temp_file"
done
}
func4() {
for i in $(seq 1 $N) ; do
while read line ; do
echo "$line"
done <"$fn" | awk "$arg" > "$temp_file"
done
}
func5() {
for i in $(seq 1 $N) ; do
readarray -t a <"$fn"
printf "%s\n" "${a[@]}" | awk "$arg" > "$temp_file"
done
}
func6() {
for i in $(seq 1 $N) ; do
awk "$arg" > "$temp_file" <"$fn"
done
}
time_it() {
temp_file="tmp_out$1.txt"
name="func$1"
{ time "$name"; } |& awk -vfn="$name" 'NR==2 {print fn, substr( $2, 3, length( $2) - 3 ) }'
}
for i in {1..6} ; do
time_it $i
done
请注意,
func1
仅用于比较。它不使用管道输入。。我们看到,对于这个特定的运行,func4
和func6
的速度大约与func1
一样快。下面是一些其他计时结果
fn="file.txt"
[[ -e $fn ]] && rm "$fn"
for i in {1..100} ; do
echo "Line $i" >> "$fn"
done
arg='{print FNR, $0}'
N=1000
func1() {
for i in $(seq 1 $N) ; do
awk "$arg" "$fn" > "$temp_file"
done
}
func2() {
for i in $(seq 1 $N) ; do
cat "$fn" | awk "$arg" > "$temp_file"
done
}
func3() {
for i in $(seq 1 $N) ; do
while read line ; do
printf "%s\n" "$line"
done <"$fn" | awk "$arg" > "$temp_file"
done
}
func4() {
for i in $(seq 1 $N) ; do
while read line ; do
echo "$line"
done <"$fn" | awk "$arg" > "$temp_file"
done
}
func5() {
for i in $(seq 1 $N) ; do
readarray -t a <"$fn"
printf "%s\n" "${a[@]}" | awk "$arg" > "$temp_file"
done
}
func6() {
for i in $(seq 1 $N) ; do
awk "$arg" > "$temp_file" <"$fn"
done
}
time_it() {
temp_file="tmp_out$1.txt"
name="func$1"
{ time "$name"; } |& awk -vfn="$name" 'NR==2 {print fn, substr( $2, 3, length( $2) - 3 ) }'
}
for i in {1..6} ; do
time_it $i
done
请注意,
func1
仅用于比较。它不使用管道输入。。我们看到,对于这个特定的运行,func4
和func6
的速度大约与func1
的速度一样快。@fedorqui谢谢。。是输入的重定向吗它记录在文档中,可以在重定向部分找到:我不完全确定它是否总是相同的。对于需要某些用户输入的命令,它可能不起作用。关于速度,在我们的示例中,命令替换$(cat文件)可以替换为等效但更快的$(<文件)。@fedorqui Ok,但命令替换可以在管道的左侧使用吗?@HåkonHægland Ok。在这种情况下,例如awk'/1/'@fedorqui谢谢。。是输入的重定向吗它记录在文档中,可以在重定向部分找到:我不完全确定它是否总是相同的。对于需要某些用户输入的命令,它可能不起作用。关于速度,在我们的示例中,命令替换$(cat文件)可以替换为等效但更快的$(<文件)。@fedorqui Ok,但命令替换可以在管道的左侧使用吗?@HåkonHægland Ok。在这种情况下,例如awk'/1/'