Использование sed в сценарии оболочки с многострочными переменными

sed -n 10p myfile | wc -c

подсчитает байты в десятой строке myfile (включая символ перевода строки / новой строки).

Немного менее читаемый вариант,

sed -n "10{p;q;}" myfile | wc -c

(или sed '10! D; q ' или sed' 10q; d ') перестанет читать файл после десятого строка, которая была бы интересна для более длинных файлов (или потоков). (Спасибо Тиму Кеннеди и Питеру Кордесу за обсуждение, приведшее к этому.)

В cat line X сравниваются характеристики различных способов извлечения строк текста. в строку Y огромного файла .

2
15.12.2016, 17:34
2 ответа

Ошибка связана с тем, что для команды sedдобавления aтребуется обратная косая черта после фактическогоa:

С GNUsed:

$ sed "/pattern/a\\$VAR" file.in >file.out

BSD sed, насколько мне известно, может вставить в файл только одну строку с помощью команды a, если символы новой строки не экранированы должным образом.

Тесно связанный ответ о том, как решить эту проблему с помощью BSDsed:http://unix.stackexchange.com/a/60322

0
27.01.2020, 22:10

Стандартный синтаксис для команды a::

sed -e 'a\
first line\
  second line\
last line'

BSD (по крайней мере, FreeBSD и OS/X)sedудаляют начальные пробелы , а требуется -eдля устранения ошибки . GNU sedпозволяет переместить первую строку сразу после a\, если она не -пуста.

Итак, вам нужно предварительно обработать ввод:

VAR='content with
multiple lines
  some with lead blanks
or even backslash\'

preprocessed_VAR=$(printf '%s\n' "$VAR" |
  sed 's/\\/&&/g;s/^[[:blank:]]/\\&/;s/$/\\/')

sed -i -e "/MatchingPattern/a\\
${preprocessed_VAR%?}" somefile

(замените -iна -i ''во FreeBSD или OS/X ).

В GNU/Linux и с оболочкой GNU(bash)или zshвы можете вместо этого:

sed -i '/MatchingPattern/r /dev/stdin' <<< "$VAR"

Это работает, потому что bashи zshреализуют здесь -строки с удаленными временными файлами, а /dev/stdin в Linux реализован как символическая ссылка на файл (, что означает, что его можно открыть несколько раз, и каждый раз он открыт в начале ).

Здесь вы также можете использовать GNU awkвместо:

(export VAR
gawk -i inplace '{print}; /MatchingPattern/{print ENVIRON["VAR"]}' somefile)

Илиperl(откуда это -iисходит):

(export VAR
perl -pi -e '$_.= "$ENV{VAR}\n" if /MatchingPattern/' somefile)
3
27.01.2020, 22:10

Теги

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