Bagaimana cara mengganti kata dengan baris baru


11

Saya memiliki file teks dengan data berikut dan setiap baris diakhiri dengan |END|.

T|somthing|something|END|T|something2|something2|END|

Saya mencoba mengganti |END|dengan \nbaris baru dengan sed.

 sed 's/\|END\|/\n/g' test.txt

Tapi itu menghasilkan output yang salah seperti di bawah ini:

 T
 |
 s
 o
 m
 e
 ...

Tapi yang saya inginkan adalah ini:

T|somthing|something
T|something2|something2

Saya juga mencoba tr. Juga tidak berhasil.


Jawaban:


15

Gunakan ini:

sed 's/|END|/\n/g' test.txt

Apa yang Anda coba tidak berhasil karena sed menggunakan ekspresi reguler dasar , dan implementasi sed Anda memiliki \|arti operator "atau" (ekstensi umum untuk BRE), jadi apa yang Anda tulis ganti (string kosong atau ENDatau string kosong) oleh baris baru.


Perlu mengomentari \ in \ n: sed 's / | END | / \\ n / g
Baazigar

@ Baaigar Tidak, apa yang ditulis AB benar (untuk Linux setidaknya, beberapa implementasi sed akan memancarkan \n). Pertanyaannya menanyakan bagaimana cara mengganti |END|dengan baris baru, bukan oleh \n.
Gilles 'SO- berhenti bersikap jahat'

Karakter untuk baris baru adalah '\ n'. \\ n diperlukan karena \ juga merupakan karakter pelarian, jadi jika Anda hanya melakukan \ n, Anda mengatakan 'lepas n karakter ini'. Ketika Anda melakukannya, Anda mengatakan 'jangan perlakukan ini selanjutnya \ sebagai pelarian.'.
Baazigar

7

Berikut ini berfungsi dengan baik untuk saya:

$ sed 's/|END|/\
/g' foobar
T|somthing|something
T|something2|something2

Perhatikan bahwa saya hanya meletakkan backslash diikuti oleh tombol enter.


2
Itu sintaks standar. Menggunakan \n seperti pada jawaban AB tidak akan bekerja dengan beberapa sedimplementasi.
Stéphane Chazelas

@ StéphaneChazelas Apa yang didukung implementasi \|untuk pergantian di regexp tetapi tidak \nberarti baris baru dalam spengganti?
Gilles 'SANGAT berhenti menjadi jahat'

5

Anda bisa menggunakan awk:

$ awk -F'\\|END\\|' '{$1=$1}1' OFS='\n' file
T|somthing|something
T|something2|something2
  • -F'\\|END\\|' setel pemisah bidang ke |END|
  • OFS='\n' atur pemisah bidang ouput ke baris baru
  • $1=$1menyebabkan awkmerekonstruksi $0dengan OFSsebagai pemisah bidang
  • 1adalah nilai sebenarnya, karena awkmencetak seluruh jalur input

3

Kemungkinan lain perintah dan menggunakan RSopsinya adalah:

awk '$1=$1' RS="\|END\|" file

Akan mencetak catatan tersebut (berdasarkan eparator R ecord S awk) yang tidak kosong (memiliki setidaknya satu bidang) untuk mencegah pencetakan garis kosong.

Diuji pada input ini:

T|somthing|something|END|T|something2|something2|END|
Test|END|
|END|

Memberikan hasil ini:

T|somthing|something
T|something2|something2
Test

Itu menghapus semua baris kosong :) Jika Anda ingin memiliki baris baru juga, ganti $1=$1dengan $0dalam perintah:

awk '$0' RS="\|END\|" file

$1=$1mengembun urutan kekosongan menjadi satu karakter spasi dan mengembalikan false jika bidang pertama adalah 0. Tidak masuk akal. Anda mungkin ingin awk 1 RS='\\|END\\|'atau awk NF RS='\\|END\\|'atau awk length RS='\\|END\\|'di sini. Perhatikan bahwa regexp RS memerlukan gawk atau mawk
Stéphane Chazelas

3

Cara lain dengan seditu tidak mencetak baris kosong:

sed 's/|END|/\
/g;/^$/!P;D' infile

misalnya input:

T|one|two|END|T|three|four|END|
T|five|six|END|T|seven|eight|END|
T|nine|ten|END|T|eleven|twelve|END|

keluaran:

T|one|two
T|three|four
T|five|six
T|seven|eight
T|nine|ten
T|eleven|twelve

hal yang sama dengan ed:

ed -s infile <<'IN'
1,$j
s/|END|/\
/g
,p
q
IN

1

Seperti yang disebutkan di sini oleh Walter Mundt , kita dapat mencapai ini menggunakan string ANSI C yang dikutip

sed $'s/|END|/\\\n/g'

~ $ echo 'T|somthing|something|END|T|something2|something2|END|' | sed 
$'s/|END|/\\\n/g'
T|somthing|something
T|something2|something2

~ $

Lihat tautan di atas di sini untuk alternatif lain.

Anda dapat menggunakan sintaks berikut juga, saya tidak yakin apakah itu berfungsi pada semua rasa Unix / Linux

sed 's/|END|/\'$'\n''/g'

~ $ echo 'T|somthing|something|END|T|something2|something2|END|' | sed 
's/|END|/\'$'\n''/g'
T|somthing|something
T|something2|something2

~ $

Bekerja pada FreeBSD v10. Sebenarnya, hanya metode yang bekerja untuk saya. Terimakasih.
Sopalajo de Arrierez

0

Saya memiliki masalah yang sama di shell posix yang ketat saya melakukannya dalam dua lulus dengan char yang tidak digunakan

cat data.json|tr '§' '?'|sed -e 's/"[^"]":/§&/g'|tr '§' '\n'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.