Как остановить sed от буферизации? - PullRequest
7 голосов
/ 23 ноября 2010

У меня есть программа, которая пишет в fd3, и я хочу обработать эти данные с помощью grep и sed. Вот как выглядит код:


exec 3> >(grep "good:"|sed -u "s/.*:\(.*\)/I got: \1/")
echo "bad:data1">&3
echo "good:data2">&3

Ничего не выводится, пока я не сделаю

exec 3>&-

Затем все, что я хотел, наконец-то приходит, как я и ожидал:

I got: data2

Кажется, я сразу отвечаю, если я использую только grep или sed, но смешивание их, похоже, вызывает некоторую буферизацию. Как я могу получить немедленный вывод из fd3?

Ответы [ 4 ]

8 голосов
/ 23 ноября 2010

Я думаю, что нашел это. По некоторым причинам, grep не выполняет автоматическую буферизацию строки. Я добавил --line-buffered параметр к grep, и теперь он немедленно реагирует.

4 голосов
/ 23 ноября 2010

Альтернативное средство остановить sed от буферизации - запустить его через s2p переводчик sed-to-Perl и вставить директиву для буферизации команд, возможнокак

BEGIN { $| = 1 }

Другая причина сделать это состоит в том, что он дает вам более удобную запись от ERE вместо устаревших BRE, раздражающих обратную косую черту.Вы также получаете полный набор свойств Unicode, который часто критичен.

Но вам не нужен переводчик для такой простой команды sed.И вам не нужны ни grep, ни sed.Все это работает:

perl -nle 'BEGIN{$|=1} if (/good:/) { s/.*:(.*)/I got: $1/; print }'

perl -nle 'BEGIN{$|=1} next unless /good:/; s/.*:(.*)/I got: $1/; print'

perl -nle 'BEGIN{$|=1} next unless /good:/; s/.*:/I got: /; print'

Теперь у вас также есть доступ к минимальному квантификатору, *?, +?, ??, {N,}? и {N,M}?.Теперь они позволяют такие вещи, как .*? или \S+? или [\p{Pd}.]??, что вполне может быть предпочтительным.

3 голосов
/ 23 ноября 2010

Вы можете объединить grep в sed следующим образом:

exec 3> >(sed -une '/^good:/s//I got: /p')
echo "bad:data1">&3
echo "good:data2">&3

Немного распаковать: Вы можете поместить регулярное выражение (как обычно, между косыми чертами) перед любой командой sed, которая делаетон применяется только к строкам, которые соответствуют этому регулярному выражению.Если первый аргумент регулярного выражения для команды s является пустой строкой (s//whatever/), то он будет повторно использовать последнее соответствующее регулярное выражение, которое в данном случае является префиксом, так что избавляет от необходимости повторяться.И, наконец, опция -n заставляет sed печатать только то, что ему конкретно предписано печатать, а суффикс /p команды s заставляет печатать результат подстановки.

Параметр -e не является строго обязательным, но это хороший стиль, он просто означает, что «следующим аргументом является сценарий sed, а не имя файла».

Всегда помещайте сценарии sed в одинарные кавычки, если только вам не нужно подставлять оболочкутам переменная, и даже тогда я бы поставил все , но переменную оболочки в одинарных кавычках (переменная оболочки, конечно, в двойных кавычках).Таким образом вы избежите кучу горя, связанной с обратной косой чертой.

2 голосов
/ 03 апреля 2015

На Mac brew install coreutils и используйте gstdbuf для управления буферизацией grep и sed.

...