Как отправить вывод `pv` в скрипт python и вывести прогресс по одной строке за раз?

Перебрать файлы и переместить их в соответствующие каталоги,

for FILE in *; do 
if [[ -f "$FILE" ]]; then 
    echo mv "$FILE" "dir${FILE##file}";
fi
done
  • if [[ -f "$FILE" ]]; then, проверьте $FILE, если это файл -f, а не каталог -d.
  • ${FILE##file}, (вырезают -вверх -до -последний -префикс )удаляет префикс fileиз имени файла и сохраняет только числовую часть.
  • Вам нужно проехать echoдля пробного прогона, чтобы иметь реальное движение.

Пример вывода:

file0 --> dir0
file1 --> dir1
file2 --> dir2
file3 --> dir3

Обновление:Если ваше имя файла имеет суффикс, например file##.xyz, вы можете использовать скрипт следующим образом:

for FILE in *; do
    if [[ -f "$FILE" ]]; then
    dname="${FILE##file}";
    echo mv "$FILE" "dir${dname%.inp}";
fi
done

Эта ${dname%.inp}часть кода (вырезает -вверх -до -первый -суффикс )удаляет .inpс конца имени файла, часть ${FILE##file}которого уже удалена его префикс fileперед,поэтому будет производиться только числовая часть.

Или даже вы можете использовать следующее.

for FILE in *; do
    if [[ -f "$FILE" ]]; then
    echo mv "$FILE" "dir${FILE//[^0-9]/}";
fi
done
2
10.11.2019, 07:15
2 ответа

pvвыводит ход выполнения в stderr, поэтому канал на скрипт python ничего не получил от pv. Он напечатал endпосле того, как вывод pvостановился, вероятно, потому, что к тому времени последний tarвышел, и поэтому стандартный ввод скрипта был закрыт.

Вам может понадобиться что-то вроде:

( sudo tar c --files-from /tmp/camfilenames | 
  pv --width 40 -f | 
  sudo tar x -C /home/pi/test ) 2>&1 >/dev/null | python /home/pi/screentest.py

Здесь мы отбрасываем стандартный вывод конвейера tar и вместо этого отправляем стандартный поток stderr скрипту python. Обратите внимание, что нам нужно принудительно вывести прогресс из pvс помощью -f, так как pvне будет выполняться, если stderr не является терминалом.

Но вы можете заглянуть в pvопцию --format. Вы можете использовать что-то вроде:

sudo tar c --files-from /tmp/camfilenames | 
  pv --width 40 --format $'%b %t\n' | 
  sudo tar x -C /home/pi/test

, чтобы получить аналогичный результат.

1
27.01.2020, 22:08

Спасибо @muru, я попробовал ваше решение, но в то же время я обнаружил, что основная проблема заключается в том, чтобы заставить PV выводить новые строки, а не просто постоянно обновлять одну строку.

Вот что я написал:

$ tail -f /home/pi/log | pv -f |& stdbuf -oL tr '\r' '\n'

И это сработало, так что теперь возник вопрос -как вызвать мой скрипт на Python, чтобы он делал что-то с каждой строкой -и я обнаружил, что могу использовать для этого цикл do -while:

$ tail -f /home/pi/log | pv -f |& stdbuf -oL tr '\r' '\n' | (while read -r LINE; do echo $LINE; done;)

Имея это, я просто использую свой скрипт Python (небольшой обработчик ЖК-дисплея )для отображения состояния PV на ЖК-дисплее:

tail -f /home/pi/log | pv -f --width 20 -i 2 |& stdbuf -oL tr '\r' '\n' | (while read -r LINE; do python /home/pi/screen.py $LINE; done;)

И я повторно -представил свой TAR-скрипт для копирования в него множества мелких файлов:

$ (sudo tar c --files-from /tmp/camfilenames | pv -f --width 20 -i 1 | sudo tar x -C /home/pi/test) |& stdbuf -oL tr '\r' '\n' | (while read -r LINE; do python /home/pi/screen.py $LINE; done;)

Итак, в конце, когда я добавляю дополнительные параметры в PV и делаю несколько замен строк перед отправкой вывода PV на ЖК-дисплей, и добавляю несколько строк разрыва, у меня есть это:

cd /home/pi/cam \ && ( \ sudo tar c --files-from /tmp/camfilenames \ | pv -f -s $( \ du -sb /home/pi/cam \ | awk '{print $1}' \ ) --width 64 -i 5 \ | sudo tar x -C /mnt/usb \ ) \ |& stdbuf -oL tr '\r' '\n' \ | ( \ while read -r LINE; \ do LINE="${LINE// /_}"; \ LINE="${LINE//_\[/ [}"; \ LINE="${LINE//\]_/] }"; \ lcd $LINE; \ done; \ ) \ && cd /home/pi

Так выглядит выход PV на ЖК-дисплее :This is how PV output looks on LCD

1
27.01.2020, 22:08

Теги

Похожие вопросы