【发布时间】:2013-09-04 11:28:09
【问题描述】:
我有一个简单的 BASH 命令,看起来像
for i in `seq 2`; do echo $i; done; > out.dat
运行时seq 2 的输出被输出到终端,没有任何内容输出到数据文件(out.dat)
我希望标准输出被重定向到 out.dat 就像它只是运行命令 seq 2 > out.dat
【问题讨论】:
我有一个简单的 BASH 命令,看起来像
for i in `seq 2`; do echo $i; done; > out.dat
运行时seq 2 的输出被输出到终端,没有任何内容输出到数据文件(out.dat)
我希望标准输出被重定向到 out.dat 就像它只是运行命令 seq 2 > out.dat
【问题讨论】:
删除分号。
for i in `seq 2`; do echo "$i"; done > out.dat
建议
正如 Fredrik Pihl 所建议的,尽量不要在不需要时使用外部二进制文件,或者至少在实际上不需要时:
for i in {1..2}; do echo "$i"; done > out.dat
for ((i = 1; i <= 2; ++i )); do echo "$i"; done > out.dat
for i in 1 2; do echo "$i"; done > out.dat
另外,请注意words 中可能导致路径名扩展的输出。
for a in $(echo '*'); do echo "$a"; done
将显示您的文件,而不仅仅是文字 *。
$() 也被推荐为在 Bash 和 POSIX shell 中比反引号 (`) 更清晰的命令替换语法,它支持嵌套。
将输出读取到变量的更简洁的解决方案是
while read var; do
...
done < <(do something)
和
read ... < <(do something) ## Could be done on a loop or with readarray.
for a in "${array[@]}"; do
:
done
就预期功能而言,使用 printf 也可以是一种更简单的替代方法:
printf '%s\n' {1..2} > out.dat
【讨论】:
seq 而不是for i in {1..2}; do ...?
(( i = 1 ; i <= 2; ++i )),或只是in 1 2 以实现兼容性。我的回答只是关于重定向的问题,尽管我试图解决一个问题:"$i"。
done 语句传递给sort 等其他内容,例如for i in foo bar baz; do echo $i | base64; done | sort | base64 -d
试试:
(for i in `seq 2`; do echo $i; done;) > out.dat
【讨论】:
{} 来执行此操作,因为不需要为子shell 创建另一个进程并保留来自更高块的变量更改.只有在无法解决的情况下才会将它们放在管道上,因为默认情况下它们被放置在子shell上,其中没有设置 laspipe 并且命令在最后,尽管使用进程替换是要走的路它。
for 循环已经是一个组合其主体的复合命令;这里的 subshell 毫无意义。
另一种可能性,为了完整起见:您可以将输出移动到循环内,使用>> 附加到文件(如果存在)。
for i in `seq 2`; do echo $i >> out.dat; done;
哪个更好当然取决于用例。一口气写完文件肯定比追加一千次要好。此外,如果循环包含多个echo 语句,所有这些语句都应该进入文件,那么执行done > out.dat 可能更具可读性和更易于维护。当然,这种解决方案的优势在于它提供了更大的灵活性。
【讨论】: