从长时间运行的命令的输出中过滤多个项目

从长时间运行的命令的输出中过滤多个项目

总括:

我如何运行 handbrakecli,获得进度ETA,管道进入对话框而不闪烁。

细节:

我有一个脚本,可以查找目录中的所有视频文件,然后一次对它们运行 handbrakecli。每次 handbrakecli 运行时,它都会吐出一堆有关文件等的信息,然后是以下行:

Encoding: task 1 of 1, 3.30 % (295.53 fps, avg 303.23 fps, ETA 00h02m54s)

在我的脚本中,我将 handbrakecli 命令通过管道传输到其他一些命令,以过滤除进度之外的所有内容,然后将其通过管道传输到对话框,如下所示:

片段1

HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST" | \
    stdbuf -o0 tr -s '\r' '\n' | \
    stdbuf -o0 grep -oP '(?<=, )\d+(?=\.\d\d \%)' | \
    dialog --gauge "$DIALOG_MSG" 10 70;

这很好用。它显示进度并且不闪烁。第二个任务是想出一种方法来显示进度和预计到达时间,这就是我想出的:

片段2

HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" | \
    stdbuf -oL tr -s '\r' '\n' | \
    while read -r str; do
        local REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))");
        local PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)");
        echo "$PROGRESS" | dialog --gauge "$DIALOG_MSG Time remaining: $REMAINING" 10 70;
    done

这有效,但对话框窗口闪烁。我不知道这是否与性能有关(对此表示怀疑),或者整个阅读时循环不能很好地与对话框配合使用。

我也尝试在不通过管道连接到对话框的情况下执行此操作,但只显示一次对话框,然后根本没有更新它。

片段3

HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" | \
    stdbuf -oL tr -s '\r' '\n' | \
    while read -r str; do
        local REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))");
        local PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)");
        dialog --gauge "$DIALOG_MSG Time remaining: $REMAINING" 10 70 $PROGRESS;
    done

最后我尝试了这个:

片段4

HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" | \
    stdbuf -o0 tr -s '\r' '\n' | (
        read -r str;                                                                                                                          
        local REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))");
        local PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)");
        echo "$PROGRESS";
    ) | dialog --gauge "$DIALOG_MSG Time remaining: $REMAINING" 10 70;

但效果并不好。

我知道这里存在一些根本性的问题。

答案1

片段 2 最接近。将选择在输入中dialog --gauge查找魔术标记,然后从下一行读取新的百分比,并从后面的行中读取新的提示,直到出现新标记。XXX

所以你应该得到你想要的:

HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" |
stdbuf -oL tr -s '\r' '\n' |
while read -r str
do
    REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))")
    PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)")
    echo -e "XXX\n$PROGRESS\n$DIALOG_MSG Time remaining: $REMAINING\nXXX"
done | 
dialog --gauge "$DIALOG_MSG Time remaining: " 10 70;

相关内容