如何在Bash循环中使用tqdm?

12

我有一个例子,其中的for loop非常耗时,所以我想使用tqdm来创建一个好看的进度条,就像在Python中一样。但是我无法找到任何方法来实现这一点。

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

如何为此循环获取进度条?

更好的方法是,在此处搜索“[linux] find xargs parallel”。假设您有多个核心和额外的内存,您可以同时处理多个文件。祝你好运。 - shellter
3个回答

6
这是一个相当古老的问题,但目前关于 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 或者 pv 命令。
使用 rsync,解决您问题的命令可以是以下内容:
rsync -avzh --progress **/*.jpg images/

5

要在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

-7
tqdm 是专门为 Python 设计的,不适用于 Bash。 如果您只是想显示循环的进度,可以使用“符号性”进度条,例如 @Mitch Haile 在问题如何将进度条添加到 Shell 脚本中? 中的回答。
您可能需要根据需求通过(已执行循环次数)/(总循环次数)来计算进度。 例如:
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;

如果你也想要一个像一系列“#”一样的“真正”的进度条,你可以计算每N个循环添加一个“#”到一个字符串中,然后输出它。

@yukashimahuksay 谢谢。实际上我不知道tqdm,也没有安装它。我只是通过谷歌发现它是Python的一个模块。 - LDecem
3
您,先生,没有阅读手册,手册中有关于在终端中使用tqdm的详细介绍 ;) - Jakob Guldberg Aaes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接