Коли я виконую команди в 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' від coreutils GNU, щоб вибрати все, крім останнього байта. Це має бути досить швидким:
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)
має той же ефект.