zaLinux.ru

Как удалить newline (символ новой строки) из вывода команд и файлов в командной строке Linux


Как удалить newline (перевод строки) из строки в Bash

Для перевода строки в операционных системах используются символы:

  • '\n' (newline)
  • '\r' (carriage return)

Причём в Linux используется \n (также называется EOL, End of Line, newline, новая строка). В других операционных системах могут быть вариации.

По умолчанию многие программы, утилиты командной строки Linux автоматически добавляют символ newline — в целом это делает вывод более читаемым. Но иногда символ перевода строки не нужен. Эта заметка посвящена тому, как убрать из строки вывода или из строк файла символ новой строки (newline).

Как удалить символ newline из строки

echo

Если вы выводите строку или результат выполнения команды с помощью «echo», то вы можете использовать опцию -n, которая означает не выводить конечный символ newline.

Обратите внимание на различный результат команд:

echo -n 'HackWare.ru' | md5sum
ce7d43633e2bfb3d283f2cfbdbeb0d2a -

echo 'HackWare.ru' | md5sum
19acfcdef400742c5de064e0bf9e9a87 -

Первая команда считает контрольную сумму строки «HackWare.ru», а вторая команда считает контрольную сумму строки «HackWare.ru» к которой добавлен конечный символ newline.

tr

Вы можете удалить конечный символ новой строки с помощью tr в конструкции

tr -d '\n'

Например:

echo 'HackWare.ru' | tr -d '\n' | md5sum
ce7d43633e2bfb3d283f2cfbdbeb0d2a -

sed

Вы можете удалить конечный символ новой строки с помощью sed в конструкции (данная команда удаляет символы «\n» и «\r»:

sed -z 's/[\n\r]//g'

Например:

echo 'HackWare.ru' | sed -z 's/[\n\r]//g' | md5sum
ce7d43633e2bfb3d283f2cfbdbeb0d2a -

Perl

Следующая конструкция на PERL также удаляет символ новой строки:

perl -pe 'chomp'

Пример:

echo 'HackWare.ru' | perl -pe 'chomp' | md5sum
ce7d43633e2bfb3d283f2cfbdbeb0d2a -

Ещё один пример использования:

wc -l < log.txt | perl -pe 'chomp'

awk

С помощью awk вы можете удалить символы newline (новой строки) используя следующую конструкцию:

awk '{ printf "%s", $0 }'

Например:

echo 'HackWare.ru' | awk '{ printf "%s", $0 }' | md5sum

Смотрите также: Уроки по Awk

Ещё один вариант:


awk '{printf $0}'

Например:

echo 'HackWare.ru' | awk '{printf $0}' | md5sum

Удаление newline из результатов выполнения команды

Все предыдущие примеры можно использовать для удаления newline из вывода команд, передав вывод по конвейеру (трубе, «|»). Далее приведены ещё несколько конструкций, которые вы можете использовать для удаления newline из результатов выполнения команды.

printf

Поместите КОМАНДУ в конструкцию вида:

printf '%s' $(КОМАНДА)

Будет выведен результат выполнения КОМАНДЫ без конечного символа newline.

Например:

printf '%s' $(echo 'HackWare.ru') | md5sum

xargs и echo

Для подавления вывода символа новой строки newline вы можете использовать конструкцию с xargs:

КОМАНДА | xargs echo -n

Будьте внимательны с предыдущей конструкцией, поскольку она также ещё и сжимает пробелы. Чтобы понять о чём идёт речь, изучите вывод следующей команды:

echo "a b" | xargs echo -n; echo -n $(echo "a b")

Поскольку xargs может быть очень медленной, вы можете использовать следующую конструкцию:

echo -n `КОМАНДА`

Помните, что если вывод начинается с -e, то предыдущая конструкция будет истолковывать вывод как опцию echo.


Подстановка команды

В следующих примерах команда, заключённая в "$(КОМАНДА)" будет выведена без конечного newline:

echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"

Как удалить только последний символ newline из многострочного вывода

Все предыдущие примеры подразумевают, что удаление символа выполняется из однострочного вывода. Если вам нужно удалить последний символ из многострочного вывода, то далее показано, как это сделать.

Perl

Следующая команда выведет содержимое файла log.txt, при этом будет удалён только один символ newline в самом конце файла, все остальные newline будут сохранены. Особенностью команды является то, что даже если файл заканчивается на несколько символов newline, все они будут удалены.

perl -pe 'chomp if eof' log.txt

printf

Следующий пример также удалит символ newline в конце файла log.txt, но удалён будет строго ПОСЛЕДНИЙ символ newline:


printf "%s" "$(< log.txt)"

Как удалить newline из файла в Bash

Вы можете использовать вывод содержимого файла в паре с любой из перечисленных выше конструкций для удаления newline. Например:

cat log.txt | tr -d '\n'

Аналог предыдущей команды:

tr -d '\n' < log.txt

Команды awk, sed, perl и другие могут как обрабатывать стандартный ввод, так и получать имена файла, который нужно обработать (удалить символы newline) в виде опции. Примеры:

awk '{ printf "%s", $0 }' log.txt
awk '{printf $0}' file
sed ':a;N;$!ba;s/\n//g' file.txt
perl -p -i -e 's/\R//g;' filename

Как удалить newline из переменной в Bash

Для удаления символа newline (или любых других символов) вы можете использовать Pattern substitution (разновидность Shell Parameter Expansion), формат следующий:

  • Для удаления всех совпадений:
${VARIABLE//FROM/TO}
  • Для удаления первого совпадения:
${VARIABLE/FROM/TO}
  • Для удаления совпадения в конце строки:
${VARIABLE/%FROM/TO}
  • Удаление всех совпадений и присвоение нового значения этой же переменной:
VARIABLE=${VARIABLE//FROM/TO}

При этом символ newline (\n) нужно экранировать обратным слэшом.

Вывод переменной без удаления newline:

text='hello\n\nthere\nagain\n'
echo -e ${text}

Результат:

hello

there
again

Вывод переменной с удалением всех newline:

text='hello\n\nthere\nagain\n'
echo -e ${text//\\n/}

Результат:

hellothereagain

Вывод переменной с удалением только первого newline:

text='hello\n\nthere\nagain\n'
echo -e ${text/\\n/}

Результат:

hello
there
again

Вывод переменной с удалением последнего newline:

text='hello\n\nthere\nagain\n'
echo -e ${text/%\\n/}

Результат:

hello

there
again

Как заменить newline ("\n") на пробел (" ")

tr

Чтобы заменить newline ("\n") на пробел вы можете использовать следующую конструкцию:


tr '\n' ' '

Например:

echo -e 'hello\n\nthere\nagain\n' | tr '\n' ' '

sed

GNU sed:

sed ':a;N;$!ba;s/\n/ /g' FILE

Кросс-платформенный совместимый синтаксис, который работает с BSD и OS X sed:

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' FILE

В GNU sed есть опция -z для записей (строк), разделённых нулём. Вы можете просто вызвать:

sed -z 's/\n/ /g'

Пример:

sed -z 's/\n/ /g' FILE

Bash

Медленное решение:

while read line; do printf "%s" "$line "; done < FILE

Ещё один вариант:

cat FILE.txt | while read line; do echo -n "$line "; done

Ещё один вариант написания:

while read line; do echo -n "$line "; done < FILE.txt

Perl

Решение на perl, скорость примерно как с sed:

perl -p -e 's/\n/ /' FILE

paste

Решение с paste, скорость примерно как с tr, может заменять только один символ:

paste -s -d ' ' FILE

awk

Решение с awk, скорость примерно как с tr:

awk 1 ORS=' ' FILE

Объяснение:

Программа awk состоит из правил, состоящих из условных кодовых блоков, то есть:

условие { кодовый блок }

Если кодовый блок опущен, используется значение по умолчанию: { print $0 }. Таким образом, 1 всегда интерпретируется как истинное условие, и для каждой строки выполняется print $0.

Когда awk читает ввод, он разбивает его на записи на основе значения RS (Record Separator, разделитель записей), который по умолчанию является newline (новой строкой), поэтому awk по умолчанию будет анализировать ввод построчно. Разделение также включает удаление RS из входной записи.

Теперь при печати записи к ней добавляется ORS (Output Record Separator, разделитель выходных записей), по умолчанию снова newline. Таким образом, поскольку мы заменили значение ORS на пробел, все символы новой строки заменяются пробелами.

Смотрите также: Уроки по Awk

Ещё один вариант, чтобы заменить все новые строки пробелами с помощью awk, не считывая весь файл в память:

awk '{printf "%s ", $0}' FILE

Если вы хотите, чтобы присутствовал финальный newline:

awk '{printf "%s ", $0} END {printf "\n"}' FILE

Вы можете использовать не только символ пробела (в данном случае вместо пробела разделителем является символ «|»):

awk '{printf "%s|", $0} END {printf "\n"}' FILE

Ещё одно просто решение на awk:

awk '{printf $0 " "}' FILE

xargs

Простое решение на xargs:

xargs < FILE.txt

Рекомендуемые статьи:

Оставить комментарий

Ваш адрес email не будет опубликован.