Intereting Posts

Выход awk имеет дополнительные возвраты каретки и буферизуется

Моя конечная цель – получить диалог прогресса zenity для работы при кодировании с помощью fdkaac.

Сначала я начал с кода, который работает, когда я кодирую «aa.wav» в «aa.mp3» с хромым. В результате получается индикатор выполнения, который плавно обновляется от 0 до 100%:

lame -m auto -V 4 aa.wav aa.mp3 | awk -vRS='\r' '(NR>3){gsub(/[()%|]/," ");print $2; fflush();}' | zenity --progress --title="Title" --text="encoding" --auto-close 

Теперь я запускаю этот код с помощью fdkaac:

 fdkaac --profile 2 --bitrate-mode 5 aa.wav -o aa.aac 

Это приводит к выходу этого экрана в конце кодирования:
[100%] 05: 31,227 / 05: 31,227 (43 раза), ETA 00: 00 000
14607096/14607096 образцов, обработанных в 00: 07.689

Во время кодирования первая строка печатается, а [100%] плавно обновляется от 0 до 100 во время кодирования. В самом конце кодирования печатается вторая строка.

Исходя из этого, я изменяю поиск gsub и заменяю на это: gsub (/ [[%] /, ""), чтобы выделить данные.

Теперь я запускаю этот код:

 fdkaac --profile 2 --bitrate-mode 5 aa.wav -o aa.aac 2>&1 | awk -vRS='\r' '(NR>3){gsub(/[\[%]/," ");print $1; fflush();}' | zenity --progress --title="Title" --text="Encoding" --auto-close 

Результат – не то, что я ожидал. Диалог прогресса появляется с 0% … и затем через некоторое время переходит на 50% … и затем исчезает, когда кодировка завершена.

Поэтому я просматриваю данные, идущие в zenity с помощью этого кода:

 fdkaac --profile 2 --bitrate-mode 5 aa.wav -o aa.aac 2>&1 | awk -vRS='\r' '(NR>3){gsub(/[\[%]/," ");print $1; fflush();}' 

Вывод экрана не тот, который я ожидал. От 1 до 50 печатаются одновременно, но по последовательным линиям, а затем по 50-100 печатаются по последовательным линиям при завершении кодирования:

1
2
3
4
5

48
49
50

и продолжается до 50, а затем выход продолжается по отдельным линиям от 50 до 100 (снова распечатывается одновременно):

50
51
52

..

98
99
100

Итак, проблема очевидна … Выходные данные печатаются двумя партиями (как это видно в диалоговом окне). И данные появляются на последовательных строках. (Выход хромой после того, как фильтр awk напечатан в одной строке и плавно обновляется).

Я подозреваю, что проблема связана с дополнительными возвратами каретки, но я не знаю, как избавиться от них. Я попытался удалить команду -vRS = '\ r .. но это не привело к выходу вообще.

Я не понимаю эту подстановку: RS = '\ r'. Где появляется переменная RS?

Мне также странно, что данные распечатываются ровно на 50% и 100%. Почему не 38% или 67%? .. поэтому данные мне что-то говорят, но я не уверен, что это такое.

Проблема может заключаться в том, что fdkaac выполняет буферизацию своего вывода, когда он подключен к трубе. Попробуйте префикс к команде:

 stdbuf -o 0 -e 0 fdkaac ... 2>&1 | ... 

где -o для stdout и -e для stderr.


Если вы хотите попробовать альтернативу awk, вы можете использовать сценарий оболочки. Убедитесь, что ваша оболочка

 stdbuf -o 0 -e 0 fdkaac ... 2>&1 | (IFS="$IFS%[]" while read -d$'\r' junk1 percent junk2 do echo "$percent" done) | zenity --progress --title="Title" --text="encoding" --auto-close 

Установив IFS (разделитель полей bash), чтобы включить еще 3 символа, «% []», они фактически становятся похожими на пробелы на входе, поэтому read с разделителем-возврат -d (-d) должно помещать первое слово строки в var junk1, второй в процентах, а остальное – в junk2. Затем мы можем просто повторить переменную, которая должна содержать только число.

Примечание: вам нужно попробовать это без бита zenity, чтобы узнать, получаете ли вы поле с номерами. Я не знаю, почему я должен был использовать первый var junk1, поскольку процент должен быть первым полем в строке, но если вы не получите желаемый номер, попробуйте удалить переменную junk1 из чтения.

Давайте awk -vRS='\r' '(NR>3){gsub(/[()%|]/," ");print $1; fflush();}' вашу команду awk: awk -vRS='\r' '(NR>3){gsub(/[()%|]/," ");print $1; fflush();}' awk -vRS='\r' '(NR>3){gsub(/[()%|]/," ");print $1; fflush();}'

Сепаратор записи – \ r, разделитель полей – [\ t] +. Символы ()% | будет заменено пространством. Вы берете первое поле.

Исходя из этого формата: [100%] 05:31.227/05:31.227 (43x), ETA 00:00.000 В [100%] 05:31.227/05:31.227 (43x), ETA 00:00.000 будут переданы: [100]

Возможно, ваш awk должен быть чем-то более похожим: awk -vRS='\r' '(NR>3){gsub(/[()%|[]]/," ");print $1; fflush();}' awk -vRS='\r' '(NR>3){gsub(/[()%|[]]/," ");print $1; fflush();}'

Или еще лучше удалить позиционный аргумент: gawk -vRS='\r' 'match($0, /([0-9]+)%/, ary) {print ary[1]}'