Как изменить файл и записать его перед печатью в STDERR

С помощью sedможно сделать

sed -E 'N;s/(.*)(\n) */\2\1/;/.{81}/s_^(.)(.{,79}[-+/*]) *_\2\1_;/^\n/!P;D' filename
  • -Eдля использования расширенных регулярных выражений, облегчающих чтение
  • Nдобавляет следующую строку в буфер
  • s/(.*)(\n) */\2\1/объединяет строки, перемещая новую строку в начало и удаляя отступы пробелов
  • /.{81}/действителен для строк, содержащих более 80 символов; в этом случае выполните s_^(.)(.{,79}[-+/*]) *_\2\1_, чтобы переместить разрыв строки на последний символ
  • /^\n/!Pесли первая строка в буфере не пуста, вывести ее
  • Dначать заново с остатком буфера

Как указал mosvy, этот скрипт имеет проблему с обратными косыми чертами в конце строки, поэтому их, вероятно, следует удалить с помощью s/\\$//. Кроме того, если бы могли быть более длинные строки ввода (, что не является проблемой OP, но, возможно, каким-то будущим читателем ), можно было бы заменить Nна /.{80}/!N. Таким образом, весь сценарий будет

sed -E 's/\\$//;/.{80}/!N;s/(.*)(\n) */\2\1/;/.{81}/s_^(.)(.{,79}[-+/*]) *_\2\1_;/^\n/!P;D' filename
-1
03.12.2020, 12:46
2 ответа

Мне удалось решить эту проблему с помощью комбинации операторов перенаправления оболочки, утилитыteeи параметра оболочкиpipefail:

set -o pipefail; somecommand 2&>1 | tee./artifact.txt; set +o pipefail

В основном это:

  1. устанавливает статус возврата конвейера как значение последней команды для выхода с ненулевым -статусом или нулем, если все команды завершились успешно.
  2. дублирует stderrиз stdoutс2&>1(или его сокращением |&), которое затем передается как stdinв teeс
  3. вызывает tee, который копирует свой stdinв stdoutпри создании копии в artifact.txt.
  4. восстанавливает исходную настройку трубы.

Мне пришлось смириться с тем, что и stdout, и stderrкопировались в файл, потому что, по-видимому, в Bash нет сокращенного синтаксиса, позволяющего передавать только stderrво вторую команду.


Другие ссылки:

1
18.03.2021, 22:46

В bashвы можете запустить:

$ somecommand 2>&1 | tee./artifact.txt;echo "${PIPESTATUS[@]}"

И получить коды выхода по всему каналу.

0
18.03.2021, 22:46

Теги

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