[英]Splitting and looping over live command output in Bash
我正在存档并使用split
生成了多个部分,同时还打印了输出文件(来自STDERR上的split
,我将其重定向到STDOUT)。 但是,直到命令返回后,才对输出数据进行循环。
无论如何,在返回命令之前,是否有必要主动分割STDOUT输出?
以下是我当前拥有的内容,但是仅在命令返回后才显示文件名列表:
export IFS=$'\n'
for line in `data_producing_command | split -d -b $CHUNK_SIZE --verbose - $ARCHIVE_PREFIX 2>&1`; do
FILENAME=`echo $line | awk '{ print $3 }'`
echo " - $FILENAME"
done
尝试这个:
data_producing_command | split -d -b $CHUNK_SIZE --verbose - $ARCHIVE_PREFIX 2>&1 | while read -r line
do
FILENAME=`echo $line | awk '{ print $3 }'`
echo " - $FILENAME"
done
但是请注意, while
循环中设置的任何变量在循环之后都不会保留其值( while
循环在子shell中运行)。
没有理由进行for循环或读取或回显。 只需将流通过管道传输到awk:
... | split -d -b $CHUNK_SIZE --verbose - test 2>&1 |
awk '{printf " - %s\n", $3 }'
您将会看到缓冲的一些延迟,但是除非您的系统非常慢或者您的感知能力很强,否则您不太可能注意到它。
在开始for
循环之前,命令替换需要运行1 。
for item in $(command which produces items); do ...
而while read -r
可以在产生第一行后立即开始消耗输出(或更实际地,在输出缓冲区已满时开始):
command which produces items |
while read -r item; do ...
1好吧,我认为从设计的角度来看并不是绝对必要的 ,但这就是目前的工作方式。
正如William Pursell已经指出的那样,没有必要在while read
循环内运行Awk,因为Awk实际上确实做得很好。
command which produces items |
awk '{ print " - " $3 }'
当然,通过最近合理的GNU Coreutils split
,您可以简单地执行
split --filter='printf " - %s\n" "$FILE"'; cat >"$FILE" ... options
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.