2017-02-22 17 views
1

У меня есть сценарий, который испускает символы «^ M» и хочет заменить их каретой UNIX на лету. В настоящее время я перенаправляю свой вывод и ошибки в файл следующим образом:Заменить «^ M» в перенаправленном stdout/stderr * на лету *

bash my_script.sh > my.log 2>&1 

Я знаю, что я могу использовать tr для выполнения замены, tr '\r' '\n', но я только знаю, как сделать это с помощью статических текстовых файлов, а также Мне нравится проверять журнал вывода, прежде чем команда завершит работу. Как сделать замену «на лету» с помощью перенаправления?

Edit: Сценарий должен иметь как стандартный вывод и поток ошибок перенаправляется в журнал.

+1

Что вы имеете в виде с * истинным возвратом каретки *? – hek2mgl

+2

@ hek2mgl Они означают возврат каретки UNIX. UNIX == true :) – slim

+3

Отрицательная терминология: нейтральные платформой _newline_/_line break_/_line final_ - лучшие термины для использования; _carriage return_ конкретно относится к символу ASCII '0xd' (CR,' \ r'), который используется как часть последовательности CRLF ('\ r \ n') в _Windows_. Если ваш ввод имеет последовательности строк CRLF - в отличие от просто CR, что редко встречается в наши дни, тогда вы должны просто _delete_ CR (представлены как '^ M') экземпляры. – mklement0

ответ

2
bash my_script.sh |& stdbuf -oL tr '\r' '\n' > my.log 
+0

Это была моя первая мысль, но это не сработало, файл журнала пуст, пока команда не завершится. – Guillochon

+0

Это из-за буферизации. См. Http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe – slim

+0

Я не уверен, что это из-за буферизации. Когда я запускаю команду с включенным 'tr', я снова вижу выход на стандартном выходе. Обычно сценарий не испускается (он попадает прямо в файл журнала). – Guillochon

2

Существует короткие руки в bash для piping как stdout и stderr в |& й просто удалить \r символ с tr в

bash script.sh |& tr '\r' '\n' > my.log 

Кроме того, вы можете отключить буферизацию вывода, если вам необходимо, выполнив stdbuf -oL, а затем команду tr сразу после нее.

+0

Как и в ответе @ slim, но это также не работает; файл журнала пуст, пока команда не завершится. Мне нужно сделать замену «на лету», причем выход по-прежнему передается в файл журнала по мере запуска сценария. – Guillochon

+0

@Guillochon: Обратитесь к моему обновлению с помощью 'stdbuf' – Inian

+0

Я дал' stdbuf' попытку, и тот же результат: до выхода команды ничего не выводить. – Guillochon

2

Вот то, что должно работать для вас:

bash myscript.sh | sed -u 's/\r/\n/' > my.log 2>&1 

Это будет делать замену на ходу, пока команда работает и до сих пор пишут в лог-файл.

Из SED людей страницы:

-u, --unbuffered 
load minimal amounts of data from the input files and flush the output buffers more often