Когда я выполняю команды в Bash (или, если быть точным, wc -l < log.txt
), вывод содержит перевод строки после него. Как мне от этого избавиться?
Когда я выполняю команды в Bash (или, если быть точным, wc -l < log.txt
), вывод содержит перевод строки после него. Как мне от этого избавиться?
Ответы:
Если ожидаемый результат - одна строка , вы можете просто удалить все символы новой строки из вывода. Было бы весьма необычно передавать по конвейеру утилиту 'tr' или Perl, если это предпочтительно:
wc -l < log.txt | tr -d '\n'
wc -l < log.txt | perl -pe 'chomp'
Вы также можете использовать подстановку команд для удаления завершающей строки:
echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"
Обратите внимание, что я не согласен с решением ФП о выборе принятого ответа. Я считаю, что по возможности следует избегать использования xargs. Да, это крутая игрушка. Нет, тебе здесь это не нужно.
Если ожидаемый результат может содержать несколько строк , вам нужно принять другое решение:
Если вы хотите удалить НЕСКОЛЬКО символов новой строки из конца файла, снова используйте подстановку cmd:
printf "%s" "$(< log.txt)"
Если вы хотите строго удалить символ последней строки из файла, используйте Perl:
perl -pe 'chomp if eof' log.txt
Обратите внимание, что если вы уверены, что у вас есть завершающий символ новой строки, который вы хотите удалить, вы можете использовать 'head' из GNU coreutils, чтобы выбрать все, кроме последнего байта. Это должно быть довольно быстро:
head -c -1 log.txt
Также, для полноты, вы можете быстро проверить, где находятся ваши символы новой строки (или другие специальные символы) в вашем файле, используя 'cat' и флаг 'show-all'. Знак доллара будет обозначать конец каждой строки:
cat -A log.txt
tr --delete '\n'
.
| tr -d '\r'
В одну сторону:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
IFS
) в одном месте. Пример echo "a b" | xargs echo -n
:; echo -n $(echo "a b")
, Это может или не может быть проблемой для варианта использования.
-e
, он будет интерпретирован как опция echo
. Это всегда безопаснее в использовании printf '%s'
.
xargs
В моей системе это происходит очень медленно (и я подозреваю, что это происходит и в других системах), поэтому printf '%s' $(wc -l log.txt)
может быть быстрее, поскольку printf
обычно является встроенным (также из-за отсутствия перенаправления информации). Никогда не используйте обратные пометки, они устарели в новых версиях POSIX и имеют многочисленные недостатки.
Существует также прямая поддержка удаления пробелов в подстановке переменных Bash :
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
Если вы назначите ее вывод переменной, bash
автоматически удаляются пробелы:
linecount=`wc -l < log.txt`
printf уже обрезает завершающий символ новой строки для вас:
$ printf '%s' $(wc -l < log.txt)
Деталь:
%s
строкового заполнителя. %s\n
), он не будет."$(command)"
, внутренние переводы будут сохранены - и будет удален только завершающий перевод строки. Оболочка выполняет всю работу здесь - printf
это просто способ вернуть результаты подстановки команд обратно stdout
.
$( )
конструкции. Вот доказательство:printf "%s" "$(perl -e 'print "\n"')"
$ printf '%s' "$(wc -l < log.txt)"
Если вы хотите удалить только последний символ новой строки , пройдите через:
sed -z '$ s/\n$//'
sed
не добавит a \0
к концу потока, если для разделителя задано значение NUL
via -z
, тогда как для создания текстового файла POSIX (с определением конца a \n
) он всегда будет выводить финал \n
без-z
.
Например:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
И доказать не NUL
добавил
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
Чтобы удалить несколько завершающих символов новой строки , проложите через:
sed -Ez '$ s/\n+$//'
sed
не предоставляет -z
.
Если вы хотите напечатать вывод чего-либо в Bash без конца строки, вы должны повторить это с помощью -n
переключателя.
Если он уже есть в переменной, отобразите его с завершающим символом новой строки :
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Или вы можете сделать это в одной строке:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)
имеет тот же эффект.