sed -n 10p myfile | wc -c
подсчитает байты в десятой строке
myfile
(включая символ перевода строки / новой строки).Немного менее читаемый вариант,
sed -n "10{p;q;}" myfile | wc -c
(или
sed '10! D; q '
илиsed' 10q; d '
) перестанет читать файл после десятого строка, которая была бы интересна для более длинных файлов (или потоков). (Спасибо Тиму Кеннеди и Питеру Кордесу за обсуждение, приведшее к этому.)
Ошибка связана с тем, что для команды sed
добавления a
требуется обратная косая черта после фактическогоa
:
С GNUsed
:
$ sed "/pattern/a\\$VAR" file.in >file.out
BSD sed
, насколько мне известно, может вставить в файл только одну строку с помощью команды a
, если символы новой строки не экранированы должным образом.
Тесно связанный ответ о том, как решить эту проблему с помощью BSDsed
:http://unix.stackexchange.com/a/60322
Стандартный синтаксис для команды 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)