如何在 bash 循环中使用 tqdm?

How to use tqdm in bash for loops?

例如,我有这个 for loop 需要很长时间才能完成,所以我想使用 tqdm 来获得一个像 python 中那样的漂亮进度条。但是我找不到任何方法来做到这一点?

for f in `find mydir -name *.jpg -print`; do cp $f images/${f//\//_}; done

如何获得此循环的进度条?

tqdm 专用于 python,不适用于 bash.. 相反,如果您只想显示循环的进度,您可能只需要一个 "symbolic" 进度条,就像@Mitch Haile 对问题 How to add a progress bar to a shell script?

的回答

您可能需要根据需要以(执行循环数)/(总循环数)来计算进度。 例如

Loop_array=(`find mydir -name *.jpg -print`);
Total_loop_num=${#Loop_array[*]};
for((i=0;i<$Total_loop_num;i++))
do
   echo -ne "Progress: $[ ($i+1)*100/$Total_loop_num ]%\r";
   f=${Loop_array[$i]};
   cp $f images/${f//\//_};
done;
echo "Loop finished.";

只要您的原始命令有效,它就应该有效。我刚刚测试了以下代码,它运行良好:

for((i=0;i<120000;i++))
do
   echo -ne "Progress: $[ ($i+1)*100/120000 ]%\r";
done;

如果你也想要一个"real"进度条,比如“#”系列,你可以计算每N个循环在一个字符串中添加一个“#”,然后回显它。

这是一个非常古老的问题,但目前 the readme for tqdm 表示在 bash 中将其用作命令可以正常工作,例如:

$ seq 9999999 | tqdm --bytes | wc -l
75.2MB [00:00, 217MB/s]
9999999

$ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
    > backup.tgz
 32%|██████████▍                      | 8.89G/27.9G [00:42<01:31, 223MB/s]

但是,tqdm 显示进度条取决于命令,该命令为其提供构建进度条的信息,而 cp 则不(甚至 cp -v 也不发送缓冲信息,因此您只会在 cp 完成后获得进度条。

就是说,如果您想要一个用于复制文件的进度条,您应该喜欢 rsync --progress or the pv 命令。

使用 rsync,解决您问题的命令可能类似于:

rsync -avzh --progress **/*.jpg images/

要在 Bash 循环中使用 tqdm,您需要:

  1. 输出一些东西
  2. 了解总迭代次数(可选)
  3. done之后添加tqdm。

你的情况:

total=1000
for f in `find mydir -name *.jpg -print`; do echo $f; cp $f images/${f//\//_}; done | tqdm --total $total >> /dev/null

查看答案:https://github.com/tqdm/tqdm/issues/436#issuecomment-330504048