Замените \ n на \ r, если строка (пришедшая из канала) содержит шаблон с GNU sed - PullRequest
1 голос
/ 07 апреля 2019

Я хочу использовать с GNU sed для замены \ n на \ r, когда каждая строка (пришедшая из канала) начинается с указанного шаблона, но моя команда sed не работает:

$ cat mpv_all.log | sed -z '/^AV:/s/\n/\r/g'

Можете ли вы помочь мне?

Ответы [ 3 ]

1 голос
/ 07 апреля 2019

, если также доступен awk:

awk '{ORS=/^AV:/?"\r":"\n"}1' file

ORS - это o utput r ecord s разделитель; который установлен на \n по умолчанию. но в приведенном выше сценарии его значение динамически изменяется на \r или \n в зависимости от того, соответствует ли строка ввода /^AV:/ (т.е. начинается с AV:) или нет.

ORS=/^AV:/?"\r":"\n" является сокращением для

if (/^AV:/)
  ORS="\r"
else
  ORS="\n"

1 в конце скрипта означает {print}.

1 голос
/ 07 апреля 2019

Проблема в том, что -z вызывает чтение всего файла за один раз. Следовательно, ^AV: соответствует, только если файл начинается с AV:. Вы, вероятно, хотите соответствовать AV: в каждой строке. В этом случае попробуйте:

sed -Ez ':a; s/((^|[\n\r])AV:[^\n\r]*)\n/\1\r/g ;ta' mpv_all.log

Как это работает:

  • -E включает расширенные регулярные выражения.

  • :a определяет метку a.

  • s/((^|[\n\r])AV:[^\n\r]*)\n/\1\r/g заменено \n на \r в конце любой строки, начинающейся с AV:.

  • ta говорит sed вернуться к метке a, если предыдущая команда замены привела к каким-либо изменениям. Это необходимо, поскольку шаблоны могут перекрываться, а модификатор g для команды s не перекрывается.

0 голосов
/ 07 апреля 2019

Просто чтобы дать реализацию perl:

$ perl -p -e '$| = 1;s/\n/\r/g if $_ =~ /^AV:/;s/Saving state/\nSaving state/;' mpv_all.log
  • -p зацикливается на каждой строке файла
  • -e запускает команду perl в кавычках
  • $| = 1; Perl очищает буфер в каждой строке
  • s/\n/\r/g if $_ =~ /^AV:/; замените \n на \r в каждой строке, начиная с AV:
  • ДОПОЛНИТЕЛЬНО: s/Saving state/\nSaving state/;помещает строку Saving state на одну строку ниже, чтобы не перезаписывать последнюю строку, содержащую AV:
...