我正在归档并使用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
答案 0 :(得分:1)
试试这个:
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中运行。)
答案 1 :(得分:1)
没有理由进行for循环或读取或回声。只需将流传输到awk:
... | split -d -b $CHUNK_SIZE --verbose - test 2>&1 |
awk '{printf " - %s\n", $3 }'
你会看到缓冲的延迟,但除非你的系统很慢或者你非常敏锐,否则你不太可能注意到它。
答案 2 :(得分:0)
命令替换需要 1 才能在for
循环开始之前运行。
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