如何在 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
,您需要:
- 输出一些东西
- 了解总迭代次数(可选)
- 在
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
例如,我有这个 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
,您需要:
- 输出一些东西
- 了解总迭代次数(可选)
- 在
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