Bagaimana saya bisa mencetak keluaran multiline pada baris yang sama?

16

Apakah ada metode untuk mencetak output multi-baris (output tunggal) pada baris yang sama?

Misalnya, jika outputnya adalah:

abc
def
qwerty

Apakah mungkin untuk mencetak:

abcdefqwerty 
Shrinidhi Kulkarni
sumber

Jawaban:

13

Anda dapat menghapus semua kemunculan karakter dari set tertentu dengan tr -d. Untuk menghapus karakter baris baru gunakan:

tr -d '\n'

Seperti biasa Anda dapat menggunakan pengalihan input dan output dan pipa untuk membaca dari atau menulis ke file dan proses lainnya.

Jika Anda ingin mempertahankan baris baru terakhir, Anda cukup menambahkannya kembali dengan echoatau printf '\n', misalnya:

cat file1 file2... | { tr -d '\n'; echo; } > output.txt
David Foerster
sumber
10

Banyak jalan. Sebagai ilustrasi, saya telah menyimpan contoh Anda di file:

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

Itu menghapus semua karakter baris baru, termasuk yang terakhir sekalipun. Anda mungkin ingin melakukan:

$ printf "%s\n" "$(cat file | perl -pe 's/\n//')"
abcdefqwerty
$ printf "%s\n" "$(cat file | tr -d '\n')"
abcdefqwerty
terdon
sumber
Saya pikir printf+ cat+ perlkombo jauh lebih baik ditangani melalui perl -pe 's/\n//;END{printf "\n"}' input.txt proses Tunggal, tidak ada substitusi perintah dan mengacaukan kutipan, dan tidak ada UUOC. Mungkin.
Sergiy Kolodyazhnyy
7

Anda dapat menyalurkan output multiline melalui awk

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

atau gunakan sed:

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

Contoh dijalankan

$ 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

Bacaan lebih lanjut: hapus jeda baris menggunakan AWK · serverfault.SE

pencuci mulut
sumber
4

Juga your_command | paste -sd ''yang mempertahankan baris baru.

glenn jackman
sumber
2

Jika Anda ingin menggunakan Perl untuk ini, Anda dapat menggunakan chompfungsinya:

perl -pe chomp

Beberapa lebih detail, bagi yang berminat.

Anda bisa memberikan satu atau lebih nama file sebagai argumen selanjutnya.

perl -pe chomp file1 file2 file3

Dalam beberapa kasus Anda mungkin tidak ingin melakukan itu , tetapi Anda dapat mengirim atau mengarahkan ke perintah itu. (Kemampuan ini - dan peringatan itu - semuanya berlaku untuk solusi lain perl -patau perl -nberbasis, juga.)

Jadi, jika Anda ingin memproses output dari menjalankan some-command:

some-command | perl -pe chomp

Ini berpotensi lebih cepat daripada perintah Perl dalam jawaban terdon . Karakter \nbaris baru (diwakili oleh ) hanya muncul di akhir baris dalam situasi ini - karena mereka adalah yang digunakan Perl untuk memutuskan di mana setiap baris berakhir. s/\n//mencari seluruh baris untuk baris baru, sementara chomphanya menghapus yang di akhir (jika ada, karena baris terakhir mungkin atau mungkin tidak memiliki satu).

Kinerja mungkin bukan alasan utama untuk memilih chomp. The perlperintah dalam jawaban Terdon ini hanya akan sedikit lebih lambat kecuali Anda sedang memproses file besar dengan garis-garis yang sangat panjang. Dan jika Anda membutuhkan kecepatan, cara David Foerster mungkin masih lebih cepat. chompadalah, bagaimanapun, alat yang tepat untuk ini jika Anda menggunakan Perl, dan saya pikir maksud chomplebih jelas dari itu s/\n//. Pada akhirnya mungkin tidak ada jawaban obyektif yang lebih baik.

Mencetak baris terakhir.

Namun, saya merekomendasikan penggunaan substitusi perintah ( $( )) hanya untuk memastikan baris baru yang tertinggal dicetak. Kecuali jika teks yang Anda proses pendek, itu kemungkinan akan sangat lambat - ia harus mengumpulkan semua teks sekaligus dan kemudian mencetaknya - dan itu membuat perintah Anda lebih sulit untuk dipahami. Sebaliknya Anda dapat melakukan seperti yang disarankan David Foerster dan jalankan echoatau printf '\n'sesudahnya.

perl -pe chomp; echo

Jika Anda mem-piping dari atau (seperti yang ditunjukkan David Foerster) mengalihkan dari perintah itu, maka Anda dapat melampirkannya { ;}sehingga output dari kedua perintah diambil secara bersamaan. Jika Anda hanya mencetaknya ke terminal, maka Anda dapat menjalankannya persis seperti yang ditunjukkan di atas. Ini berfungsi bahkan jika Anda mengirim atau mengarahkan ke perintah, karena echo/ printf '\n'sebenarnya tidak membaca input apa pun. Artinya, ini berfungsi:

some-command | perl -pe chomp; echo

Sementara di sini Anda tidak bisa menghapus { ;}:

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

Atau, jika Anda mau, Anda bisa perlmencetak sendiri baris terakhir. Seperti melampirkan perldan echoperintah dalam { ;}, pendekatan ini bekerja bahkan jika Anda perpipaan sedang atau mengarahkan dari itu (dan, seperti semua pendekatan, karya ini ketika Anda perpipaan sedang untuk itu, juga):

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

Perhatikan bahwa perintah dalam jawaban terdon berfungsi dengan baik dengan metode pencetakan baris terakhir akhir ini. Sebagai contoh:

perl -pe 's/\n//'; echo
perl -pe 's/\n//; END { print "\n" }'
Eliah Kagan
sumber
perl -wpe 'chomp; END { print "\n" } adalah proses yang sama, keuntungan kecil daripada menambahkan trailing echo
Sergiy Kolodyazhnyy
1

Menggunakan cara shell-only:

while IFS= read -r line || [ -n "$line" ]; do printf "%s"  "$line"; done < inputfile.txt
Sergiy Kolodyazhnyy
sumber
1

Jawaban ini memiliki solusi untuk masalah yang Anda coba buat: Mengapa bash menghapus \ n dalam $ (file cat)?

Jika Anda mengetik, cat myfile.txtAnda akan melihat:

abc
def
ghi

Tetapi jika Anda mengetik, echo $(cat myfile.txt)Anda akan melihat:

abc def ghi

Perhatikan metode ini menyisipkan ruang di mana garis-garis baru terpisah dulu. Ini membuat output lebih mudah dibaca tetapi tidak sepenuhnya mematuhi ruang lingkup pertanyaan Anda.

WinEunuuchs2Unix
sumber
0

Jika Anda menggunakan Bash, maka Anda dapat melakukannya tanpa alat eksternal.

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

Hasil:

line1 line2

Perintah pertama mengubah output multiline menjadi sebuah array, perintah kedua memperluas array menjadi beberapa argumen pada satu baris.

osexp2003
sumber