繁体   English   中英

在Bash中拆分和循环实时命令输出

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM