Как я могу напечатать многострочный вывод на одной строке?

16

Есть ли способ напечатать многострочный вывод (один вывод) на одной строке?

Например, если вывод:

abc
def
qwerty

Можно ли распечатать:

abcdefqwerty 
Шринидхи Кулкарни
источник

Ответы:

13

Вы можете удалить все вхождения символов из данного набора с помощью tr -d. Чтобы удалить символ новой строки, используйте:

tr -d '\n'

Как всегда, вы можете использовать перенаправление ввода и вывода и каналы для чтения или записи в файлы и другие процессы.

Если вы хотите сохранить последний символ новой строки, вы можете просто добавить его обратно с помощью echoили printf '\n', например:

cat file1 file2... | { tr -d '\n'; echo; } > output.txt
Дэвид Фёрстер
источник
10

Много способов. Чтобы проиллюстрировать это, я сохранил ваш пример в file:

$ cat file | tr -d '\n'
abcdefqwerty$ 
$ cat file | perl -pe 's/\n//'
abcdefqwerty$ 

Это удаляет все символы новой строки, включая последний, хотя. Вы могли бы вместо этого хотеть сделать:

$ printf "%s\n" "$(cat file | perl -pe 's/\n//')"
abcdefqwerty
$ printf "%s\n" "$(cat file | tr -d '\n')"
abcdefqwerty
terdon
источник
Я думаю, что printf+ cat+ perlкомбо намного лучше обрабатывается с помощью perl -pe 's/\n//;END{printf "\n"}' input.txt одного процесса, без подстановки команд и работы с кавычками, а также без UUOC. Может быть.
Сергей Колодяжный
7

Вы можете передать свой многострочный выход через awk

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

или используйте sed:

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

Пример запуска

$ echo -e "1\n2\n3\n4" | awk '{printf "%s",$0} END {print ""}'
1234
$ echo -e "1\n2\n3\n4" | sed ':a;N;$!ba;s/\n//g'              
1234

Дальнейшее чтение: удалить разрыв строки, используя AWK · serverfault.SE

Десерт
источник
4

Также, your_command | paste -sd ''который сохраняет завершающий перевод строки.

Гленн Джекман
источник
2

Если вы хотите использовать Perl для этого, вы можете использовать его chompфункцию:

perl -pe chomp

Еще несколько подробностей, для тех, кому интересно.

Вы можете передать одно или несколько имен файлов в качестве последующих аргументов.

perl -pe chomp file1 file2 file3

В некоторых случаях вы можете этого не делать , но вместо этого вы можете направить или перенаправить на эту команду. (Эти способности - и это предостережение - все применимы и к любому другому perl -pили perl -nоснованному решению).

Итак, если вы хотите обработать вывод из работы some-command:

some-command | perl -pe chomp

Это потенциально быстрее, чем команда Perl в ответе Тердона . Символы новой \nстроки (представленные ) появляются только в конце строк в этой ситуации - потому что именно они используются Perl, чтобы решить, где заканчивается каждая строка. s/\n//просматривает всю строку на наличие новых строк, в то время как chompпросто удаляет строку в конце (если есть, так как последняя строка может иметь или не иметь ее).

Производительность не может быть главной причиной предпочтения chomp. Команда perlв ответе Тердона будет только немного медленнее, если вы не обрабатываете огромный файл с очень длинными строками. И если вам нужна скорость, путь Дэвида Фёрстера все еще, вероятно, быстрее. chompоднако, это именно тот инструмент, который вам подходит, если вы используете Perl, и я думаю, что цель chompболее ясна, чем цель s/\n//. В конечном счете, вероятно, нет объективного ответа о том, что лучше.

Печать последней строки.

Тем не менее, я рекомендую не использовать команду substitution ( $( )) только для того, чтобы печатать завершающий символ новой строки. Если текст, который вы обрабатываете, не будет коротким, он, вероятно, будет довольно медленным - он должен собрать весь текст сразу, а затем распечатать его - и это затруднит понимание вашей команды. Вместо этого вы можете сделать, как предложил Дэвид Фёрстер, и бежать, echoили printf '\n'после.

perl -pe chomp; echo

Если вы работаете с или (как показывает Дэвид Фёрстер) перенаправление с этой команды, то вы можете заключить ее { ;}так, чтобы выходные данные обеих команд были взяты вместе. Если вы просто распечатываете его в терминал, вы можете запустить его точно так, как показано выше. Это работает , даже если вы трубопроводы или перенаправлять к команде, потому что echo/ printf '\n'фактически не требует никакого ввода. То есть это работает:

some-command | perl -pe chomp; echo

Хотя здесь вы не можете просто удалить { ;}:

{ perl -pe chomp; echo; } | some-other-command

Или, если вы предпочитаете, вы можете perlраспечатать окончательный перевод новой строки. Как заключени perlи echoкоманды в { ;}этом подходе работает , даже если вы трубопроводы или перенаправление от него (и, как всех подходы, это работает , когда вы трубопроводы к ним, тоже):

perl -wpe 'chomp; END { print "\n" }'

Обратите внимание, что команда в ответе Тердона прекрасно работает и с этими способами печати последней строки. Например:

perl -pe 's/\n//'; echo
perl -pe 's/\n//; END { print "\n" }'
Элия ​​Каган
источник
perl -wpe 'chomp; END { print "\n" } это тот же процесс, незначительное преимущество перед добавлением конечного эха
Сергей Колодяжный
1

Используя только оболочку:

while IFS= read -r line || [ -n "$line" ]; do printf "%s"  "$line"; done < inputfile.txt
Сергей Колодяжный
источник
1

Этот ответ имеет решение проблемы, которую вы пытаетесь создать: почему bash удаляет \ n в $ (файл cat)?

Если вы напечатаете, cat myfile.txtвы увидите:

abc
def
ghi

Но если вы напечатаете, echo $(cat myfile.txt)вы увидите:

abc def ghi

Обратите внимание, этот метод вставляет пробел, где раньше были отдельные новые строки. Это облегчает чтение результатов, но не строго соответствует объему вашего вопроса.

WinEunuuchs2Unix
источник
0

Если вы используете Bash, то вы можете сделать это без каких-либо внешних инструментов.

x=($(echo line1; echo line2))
echo "${x[@]}"

Результат:

line1 line2

Первая команда превращает многострочный вывод в массив, вторая команда расширяет массив до нескольких аргументов в одной строке.

osexp2003
источник