Bagaimana cara menggabungkan beberapa baris output ke satu baris?

157

Jika saya menjalankan perintah cat file | grep pattern, saya mendapatkan banyak garis keluaran. Bagaimana Anda menggabungkan semua garis menjadi satu baris, secara efektif mengganti masing "\n"- masing dengan "\" "(diakhiri dengan "diikuti oleh spasi)?

cat file | grep pattern | xargs sed s/\n/ /g tidak bekerja untuk saya.

T. Webster
sumber
Ngomong-ngomong: (1) Anda perlu menempatkan sedskrip Anda dalam tanda kutip tunggal sehingga Bash tidak mengacaukannya (karena sed s/\n/ /gpanggilan seddengan dua argumen, yaitu s/n/dan /g); (2) karena Anda ingin output cat file | grep patternmenjadi masukan untuk sed, bukan argumen untuk sed, Anda perlu menghilangkan xargs; dan (3) tidak perlu untuk di catsini, karena grepdapat menggunakan nama file sebagai argumen kedua. Jadi, Anda harus mencoba grep pattern file | sed 's/\n/ /g'. (Dalam hal ini itu tidak akan berhasil, untuk alasan yang diberikan pada tautan di atas, tetapi sekarang Anda tahu untuk masa depan.)
ruakh
mirip dengan " stackoverflow.com/questions/2764051/... "
Shervin Emami
Pertanyaan dengan 68 suara (140k tampilan) digandakan dengan posting yang hanya memiliki 1 suara (12k dilihat)? Ini tidak benar.
kenorb

Jawaban:

230

Gunakan tr '\n' ' 'untuk menerjemahkan semua karakter baris baru ke spasi:

$ grep pattern file | tr '\n' ' '

Catatan: grepmembaca file, catmenggabungkan file. Jangancat file | grep !

Edit:

trhanya dapat menangani terjemahan karakter tunggal. Anda dapat menggunakan awkuntuk mengubah pemisah rekaman keluaran seperti:

$ grep pattern file | awk '{print}' ORS='" '

Ini akan mengubah:

one
two 
three

untuk:

one" two" three" 
Chris Seymour
sumber
3
Anda berakhir dengan ruang yang tidak diinginkan di akhir dengan pendekatan ini.
sorin
1
Anda harus menambahkan echo ""di akhir untuk menambahkan baris baru sebelum teks prompt.
nexayq
1
Ini berfungsi dengan baik, namun saya tidak ingin separator muncul di entri terakhir. Contoh, menurut Anda ", itu terlihat seperti one" two" three", namun saya ingin itu muncul seperti one" two" three. Perhatikan tiga terakhir tidak memiliki tanda kurung. Ada ide?
Oink
2
@oink Anda dapat menyalurkan hasilnya ke sed '$s/..$//'untuk menghapus 2 karakter terakhir di baris terakhir.
Chris Seymour
3
Jika Anda ingin mengganti baris baru dengan apa pun, Anda perlu menggunakan --delete opsi karena default mengharapkan dua argumen. mis tr --delete '\n'.
Elijah Lynn
69

Piping output to xargsakan menyatukan setiap baris output ke satu baris dengan spasi:

grep pattern file | xargs

Atau perintah apa pun, mis. ls | xargs. Batas xargskeluaran standar adalah ~ 4096 karakter, tetapi dapat ditingkatkan dengan mis.xargs -s 8192.

bluebadge
sumber
| tr '\n' ' 'tidak bekerja untuk saya ketika dipanggil melalui php execfungsi. Itu mengabaikan tr, dan hanya memberikan pertandingan terakhir dari grep. | xargsbekerja.
Adarsha
3
Solusi ini juga memiliki keuntungan karena 'memakan' spasi dari input. +1
Rene
55

Di bash echotanpa tanda kutip, hapus carriage return, tab, dan beberapa spasi

echo $(cat file)
pengguna1699917
sumber
8
Jawaban yang sangat diremehkan di sini, ini benar-benar sederhana dan berfungsi seperti pesona, dengan baris baru yang tertinggal juga.
Dangercrow
Ini sangat rapi jika Anda menggunakanIFS="$(printf '\n\t')"
aggsol
5
Atau hanya echo $(<file)... menggunakan gema tidak hanya lebih rapi daripada menggunakan tr '\n' ' ', tetapi juga lebih baik (pikirkan \r\nakhir baris). @aggsol, Anda bisa mengatakanIFS=$'\n\t'
Normadize
Bagaimana tanpa ruang?
DimiDak
22

Ini bisa menjadi apa yang Anda inginkan

cat file | grep pattern | paste -sd' '

Mengenai hasil edit Anda, saya tidak yakin apa artinya, mungkin ini?

cat file | grep pattern | paste -sd'~' | sed -e 's/~/" "/g'

(ini mengasumsikan bahwa ~tidak terjadi di file)

lihat
sumber
2
@Stephan tidak perlu berasumsi bahwa cat fileitu benar-benar akan cat, atau bahkan file. (Saya baru saja membiarkan bagian itu tidak berubah karena tidak relevan dengan pertanyaan)
lihat
5

Ini adalah contoh yang menghasilkan keluaran terpisah dengan koma. Anda dapat mengganti koma dengan pemisah apa pun yang Anda butuhkan.

cat <<EOD | xargs | sed 's/ /,/g'
> 1
> 2
> 3
> 4
> 5
> EOD

menghasilkan:

1,2,3,4,5
Richard Gomes
sumber
3

Berikut adalah metode menggunakan exeditor (bagian dari Vim ):

  • J oin semua lini dan p etak ke output standar:

    $ ex +%j +%p -scq! file
  • Hanya semua baris di tempat (dalam file):

    $ ex +%j -scwq file

    Catatan: Ini akan menggabungkan semua baris di dalam file itu sendiri!

kenorb
sumber
2

Cara tercepat dan termudah yang saya tahu untuk mengatasi masalah ini:

Saat kami ingin mengganti karakter baris baru \n dengan spasi :

xargs < file

xargsmemiliki batas sendiri pada jumlah karakter per baris dan jumlah semua karakter yang digabungkan, tetapi kita dapat meningkatkannya. Detail dapat ditemukan dengan menjalankan perintah ini: xargs --show-limitsdan tentu saja dalam manual:man xargs

Saat kami ingin mengganti satu karakter dengan yang lainnya tepat satu karakter :

tr '\n' ' ' < file

Saat kami ingin mengganti satu karakter dengan banyak karakter :

tr '\n' '~' < file | sed s/~/many_characters/g

Pertama, kami mengganti karakter baris baru \nuntuk tildes ~(atau memilih karakter unik lain yang tidak ada dalam teks), dan kemudian kami mengganti karakter tilde dengan karakter lain ( many_characters) dan kami melakukannya untuk setiap tilde (bendera g).

simhumileco
sumber
0

Mungkin cara terbaik untuk melakukannya adalah menggunakan alat 'awk' yang akan menghasilkan output menjadi satu baris

$ awk ' /pattern/ {print}' ORS=' ' /path/to/file

Ini akan menggabungkan semua garis menjadi satu dengan pembatas ruang

Vladimir Yahello
sumber
Anda tidak perlu {print}karena ini adalah tindakan standar awk.
stark
0

Berikut adalah metode sederhana lain menggunakan awk:

# cat > file.txt
a
b
c

# cat file.txt | awk '{ printf("%s ", $0) }'
a b c

Juga, jika file Anda memiliki kolom, ini memberikan cara mudah untuk menggabungkan hanya kolom tertentu:

# cat > cols.txt
a b c
d e f

# cat cols.txt | awk '{ printf("%s ", $2) }'
b e
ascendant
sumber
-1

Di red hat linux saya hanya menggunakan echo:

echo $ (cat / some / file / name)

Ini memberi saya semua catatan file hanya pada satu baris.

pengguna13498546
sumber
2
Ini sudah dijawab pada tahun 2015. Anda hanya menduplikasi jawaban ini . Silakan baca jawaban sebelum memposting jawaban Anda sendiri, khususnya ketika pertanyaannya adalah 7 tahun dan sudah ada 8 jawaban.
Mickael B.