如何计算来自 stdin 的行数并让读取循环对其进行操作?



我有一个filenotfound脚本如下:

# Check if filenames listed in a text file exist.
while read -r || [[ -n $REPLY ]]; do
# Check if file (local or with full path) exists.
[[ -f $REPLY ]] && continue
# Filename with some wrong path.
... "long" processing (try to find file elsewhere, with same name)...
done

我以以下方式使用:

cat list-of-files.txt | filenotfound

我想根据stdin上给出的行数添加一个进度条(以便可以准确监控进度(。

我怎样才能从stdin中计算出行数,并让while读取循环对其进行操作?(如果可能,不使用临时文件(

PS-进度条的代码,可在如何将进度条添加到shell脚本中?中找到。

更新 --是否可以不向filenotfound添加参数,并通过使用tee、子壳或类似的东西来获得我想要的东西?

您可以使用echo -ne覆盖现有行。您需要wc -l输入文件才能知道有多少行,并计算每行的预分位数。然后在您的 for 循环中,进行预分计算并用echo -ne打印它:

echo -ne '#####                     (33%)r'
sleep 1
echo -ne '#############             (66%)r'
sleep 1
echo -ne '#######################   (100%)r'

这将在同一行打印进度。

编辑:为了在您的脚本中实现它,请尝试以下操作:

num_lines=$1
each_row=$(echo "scale=2; (1/$num_lines) * 100" | bc)
function printProgress() {
echo -ne "#"
}
for ((i=0;i<$num_lines;i++))
do
# your code
val=${each_row%.*}
while [ $val -gt 0 ]; do
printProg
let "val--"
sleep 1
done
done

然后运行你的脚本,用行数作为你的第一个参数,使用cat list-of-files.txt | filenotfound $(wc -l list-of-files.txt)

对于真正的进度条(但不是线性的,如 Inian 所述(,您必须修改脚本以使其打印出来。但为了做到这一点,它还需要事先知道条目总数。因此,假设每行list-of-files.txt有一个条目,您可以向脚本添加一个输入参数,然后:

n=list-of-files.txt; cat $n | filenotfound $(wc -l $n)

最新更新