Как удалить конечную новую строку в bash?

Я ищу что-то, что ведет себя как перлы Перла. Я ищу команду, которая просто печатает свой вход, минус последний символ, если это новая строка:

 $ printf "one\ntwo\n" | COMMAND_IM_LOOKING_FOR ; echo " done" one two done $ printf "one\ntwo" | COMMAND_IM_LOOKING_FOR ; echo " done" one two done 

(Подстановка команд в Bash и Zsh удаляет все завершающие новые строки, но я ищу что-то, что удаляет одну завершающую новую строку максимум).

  • Сценарий оболочки для назначения значений из таблицы поиска слишком медленный
  • Скрипт для отправки почты, если в журнале не было записи в течение определенного времени
  • Скрипт, который будет читать 5 чисел, а затем сортировать с самого высокого на самый низкий
  • Доступ к Google-трансляции через wget
  • Как я могу манипулировать подкаталогами в оболочке?
  • проанализировать файл журнала, который принимает аргумент (время выполнения тестов)
  • Как я могу найти учетную запись пользователя в различных конфигурационных файлах, связанных с sudo?
  • cd в скрипте bash без псевдонима, функция, источник
  • 4 Solutions collect form web for “Как удалить конечную новую строку в bash?”

    Это должно работать:

     printf "one\ntwo\n" | awk 'NR>1{print PREV} {PREV=$0} END{printf("%s",$0)}' ; echo " done" 

    Сценарий всегда печатает предыдущую строку вместо текущей, а последняя строка обрабатывается по-разному.

    Что он делает более подробно:

    1. NR>1{print PREV} Печать предыдущей строки (кроме первого раза).
    2. {PREV=$0} Сохраняет текущую строку в переменной PREV .
    3. END{printf("%s",$0)} Наконец, напечатайте последнюю строку с разрывом строки.

    Также обратите внимание, что это приведет к удалению не более одной пустой строки в конце (без поддержки для удаления "one\ntwo\n\n\n" ).

    Вы можете использовать perl без chomp :

     $ printf "one\ntwo\n" | perl -0 -pe 's/\n\Z//'; echo " done" one two done $ printf "one\ntwo" | perl -0 -pe 's/\n\Z//'; echo " done" one two done 

    Но почему бы не использовать сам chomp :

     $ printf "one\ntwo\n" | perl -pe 'chomp if eof'; echo " done" 

    Если вам нужен точный эквивалент chomp , первым методом, который приходит мне на ум, является решение awk, которое уже опубликовано в LatinSuD . Я добавлю некоторые другие методы, которые не реализуют chomp но реализуют некоторые общие задачи, для которых часто используется chomp .

    Когда вы вставляете какой-либо текст в переменную, все строки новой строки заканчиваются. Таким образом, все эти команды производят один и тот же однострочный вывод:

     echo "$(printf 'one\ntwo') done" echo "$(printf 'one\ntwo\n') done" echo "$(printf 'one\ntwo\n\n') done" echo "$(printf 'one\ntwo\n\n\n\n\n\n\n\n\n\n') done" 

    Если вы хотите добавить какой-либо текст в последнюю строку файла или из вывода команды, sed может быть удобным. С GNU sed и большинством других современных реализаций это работает, даже если вход не заканчивается новой строкой¹; однако это не добавит новой строки, если ее уже не было.

     sed '$ s/$/ done/' 

    ¹ Однако это не работает со всеми реализациями sed: sed – это инструмент обработки текста, а файл, который не пуст и не заканчивается символом новой строки, не является текстовым файлом.

    Другой подход perl . Этот считывает весь ввод в память, поэтому может быть хорошей идеей для больших объемов данных (используйте для этого подход cuonglm или awk ):

     $ printf "one\ntwo\n" | perl -00pe 's/\n$//'; echo " done" one two done 
    Linux и Unix - лучшая ОС в мире.