Pertanyaan Bagaimana cara mengganti baris baru (\ n) menggunakan sed?


Bagaimana cara mengganti baris baru (\n) menggunakan perintah sed?

Saya tidak berhasil mencoba:

sed 's#\n# #g' file
sed 's#^$# #g' file

Bagaimana saya memperbaikinya?


1125
2017-08-09 19:10


asal


Jawaban:


Gunakan solusi ini dengan GNU sed:

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

Ini akan membaca seluruh file dalam satu lingkaran, lalu mengganti baris baru dengan spasi.

Penjelasan:

  1. Buat label melalui :a.
  2. Tambahkan baris saat ini dan selanjutnya ke ruang pola via N.
  3. Jika kita sebelum baris terakhir, cabang ke label yang dibuat $!ba ($! berarti tidak melakukannya di baris terakhir karena harus ada satu baris baru final).
  4. Akhirnya substitusi menggantikan setiap baris baru dengan ruang pada ruang pola (yang merupakan keseluruhan file).

Berikut ini sintaks yang kompatibel lintas platform yang bekerja dengan BSD dan OS X's sed (sesuai @Benjie komentar):

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file

1278
2017-08-09 20:26



Menggunakan tr sebagai gantinya?

tr '\n' ' ' < input_filename

atau hapus karakter baris baru seluruhnya:

tr -d '\n' < input.txt > output.txt

atau jika Anda memiliki versi GNU (dengan opsi panjangnya)

tr --delete '\n' < input.txt > output.txt

1447
2017-08-09 19:16



Jawaban cepat:

sed ':a;N;$!ba;s/\n/ /g' file
  1. :Sebuah  buat label 'a'
  2. N  tambahkan baris berikutnya ke ruang pola
  3. $!  jika bukan baris terakhir, ba  cabang (buka) label 'a'
  4. s  pengganti, / \ n /  regex untuk baris baru, / /  dengan spasi, / g  pertandingan global (sebanyak mungkin)

sed akan mengulang melalui langkah 1 hingga 3 sampai mencapai baris terakhir, membuat semua garis sesuai dengan ruang pola di mana sed akan mengganti semua karakter \ n


Alternatif:

Semua alternatif, tidak seperti sed tidak perlu mencapai baris terakhir untuk memulai proses

dengan pesta, lambat

while read line; do printf "%s" "$line "; done < file

dengan perl, sed-seperti kecepatan

perl -p -e 's/\n/ /' file

dengan tr, lebih cepat dari sed, dapat menggantikan hanya dengan satu karakter

tr '\n' ' ' < file

dengan pasta, tr-seperti kecepatan, dapat menggantikan hanya dengan satu karakter

paste -s -d ' ' file

dengan awk, tr-seperti kecepatan

awk 1 ORS=' ' file

Alternatif lain seperti "echo $ (<file)" lambat, hanya berfungsi pada file kecil dan perlu memproses seluruh file untuk memulai proses.


Jawaban panjang dari sed FAQ 5.10:

5.10. Mengapa saya tidak bisa mencocokkan atau menghapus baris baru menggunakan \ n melarikan diri
      urutan? Mengapa saya tidak dapat mencocokkan 2 atau lebih baris menggunakan \ n?

\ N tidak akan pernah cocok dengan baris baru di akhir baris karena
   baris baru selalu dilucuti sebelum garis ditempatkan ke dalam
   ruang pola. Untuk mendapatkan 2 atau lebih garis ke dalam ruang pola, gunakan
   perintah 'N' atau yang serupa (seperti 'H; ...; g;').

Sed bekerja seperti ini: sed membaca satu baris pada satu waktu, memotong
   mengakhiri baris baru, menempatkan apa yang tersisa ke dalam ruang pola di mana
   skrip sed dapat mengatasi atau mengubahnya, dan ketika ruang pola
   dicetak, menambahkan baris baru ke stdout (atau ke file). Jika itu
   ruang pola sepenuhnya atau sebagian dihapus dengan 'd' atau 'D', yang
baris baru adalah tidak ditambahkan dalam kasus seperti itu. Jadi, skrip seperti

  sed 's/\n//' file       # to delete newlines from each line             
  sed 's/\n/foo\n/' file  # to add a word to the end of each line         

TIDAK AKAN PERNAH berfungsi, karena baris baru di belakang dihapus sebelum
   garis dimasukkan ke dalam ruang pola. Untuk melakukan tugas-tugas di atas,
   gunakan salah satu dari skrip ini sebagai gantinya:

  tr -d '\n' < file              # use tr to delete newlines              
  sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines             
  sed 's/$/ foo/' file           # add "foo" to end of each line          

Karena versi sed selain GNU sed memiliki batasan untuk ukuran
   buffer pola, utilitas Unix 'tr' lebih disukai di sini.
   Jika baris terakhir dari file berisi baris baru, GNU sed akan ditambahkan
   bahwa baris baru ke output tetapi menghapus semua yang lain, sedangkan tr akan
   hapus semua baris baru.

Untuk mencocokkan blok dua atau lebih baris, ada 3 pilihan dasar:
   (1) gunakan perintah 'N' untuk menambahkan baris Berikutnya ke ruang pola;
   (2) gunakan perintah 'H' setidaknya dua kali untuk menambahkan baris saat ini
   ke ruang Tahan, lalu ambil garis dari ruang penyimpanan
   dengan x, g, atau G; atau (3) menggunakan rentang alamat (lihat bagian 3.3, di atas)
   untuk mencocokkan garis antara dua alamat yang ditentukan.

Pilihan (1) dan (2) akan menempatkan \ n ke dalam ruang pola, di mana itu
   dapat diatasi sesuai keinginan ('s / ABC \ nXYZ / alfabet / g'). Satu contoh
   menggunakan 'N' untuk menghapus blok garis muncul di bagian 4.13
   ("Bagaimana cara menghapus blok spesifik baris berturut-turut? "). Ini
   Contoh dapat dimodifikasi dengan mengubah perintah delete menjadi sesuatu
   lain, seperti 'p' (cetak), 'i' (insert), 'c' (ubah), 'a' (tambahkan),
   atau 's' (pengganti).

Pilihan (3) tidak akan menempatkan \ n ke dalam ruang pola, tetapi itu tidak
   cocok dengan blok baris berturut-turut, jadi mungkin itu tidak Anda lakukan
   bahkan perlu \ n untuk mencari apa yang Anda cari. Sejak GNU sed
   versi 3.02.80 sekarang mendukung sintaks ini:

  sed '/start/,+4d'  # to delete "start" plus the next 4 lines,           

selain rentang tradisional '/ dari sini /, / ke sana / {...}'
   alamat, dimungkinkan untuk menghindari penggunaan sepenuhnya.


412
2017-10-08 14:55



Alternatif awk yang lebih pendek:

awk 1 ORS=' '

Penjelasan

Program awk dibangun dari aturan yang terdiri dari blok kode bersyarat, yaitu:

condition { code-block }

Jika blok kode diabaikan, default digunakan: { print $0 }. Jadi, itu 1 Diartikan sebagai kondisi yang benar dan print $0 dijalankan untuk setiap baris.

Kapan awk membaca masukan itu membagi itu menjadi catatan berdasarkan nilai RS (Record Separator), yang secara default adalah newline, jadi awk secara default akan mengurai baris-bijaksana masukan. Pemisahan juga melibatkan pengupasan RS dari catatan input.

Sekarang, saat mencetak rekaman, ORS (Output Record Separator) ditambahkan ke dalamnya (default lagi adalah baris baru). Jadi dengan berubah ORSke ruang semua baris baru diubah ke spasi.


175
2018-02-13 12:12



gnu sed memiliki opsi -z untuk catatan yang tidak terpisahkan (garis). Anda cukup memanggil:

sed -z 's/\n/ /g'

91
2018-05-05 09:43



Itu Perl versi berfungsi seperti yang Anda harapkan.

perl -i -p -e 's/\n//' file

Seperti yang ditunjukkan dalam komentar, perlu dicatat bahwa pengeditan ini sudah ada. -i.bak akan memberi Anda cadangan file asli sebelum pengganti jika Anda ekspresi reguler tidak sepintar yang kamu pikirkan.


75
2017-08-09 19:25



Siapa yang butuh sed? Ini dia bash cara:

cat test.txt |  while read line; do echo -n "$line "; done

40
2017-08-11 12:07