Ganti \ n dengan baris baru dengan mudah

23

Saya sangat bingung dengan berbagai pilihan GNU sed, POSIX sed, dan BSD sed. Bagaimana cara mengganti literal \ndengan karakter baris baru menggunakan tiga sedjenis ini?

Avinash Raj
sumber
Mereka memiliki banyak hal yang berbeda, bagian mana yang ingin Anda ketahui?
cuonglm
@ Gouc saya pikir sekarang sudah jelas.
Avinash Raj
1
Apakah Anda sudah melihat pertanyaan ini ?
groxxda
2
Apa yang Anda inginkan terjadi pada input seperti foo\\nbaratau foo\\\nbar?
Gilles 'SANGAT berhenti menjadi jahat'
sederhana, foo \\ pada baris berikutnya akan menjadi bar.
Avinash Raj

Jawaban:

30
sed 's/\\n/\
/g'

Perhatikan garis miring terbalik tepat sebelum memukul balik dalam string pengganti.

unxnut
sumber
apakah ini bekerja untuk semua jenis sed?
Avinash Raj
Saya percaya itu harus; Saya diuji hanya di Linux menggunakan versi gnu.
unxnut
11
@AvinashRaj. Itu POSIX dan bekerja dengan sedperintah asli di Unix v7 pada tahun 1979. Satu-satunya tempat di mana yang mungkin tidak akan berfungsi adalah implementasi stripped-down non-POSIX sedseperti beberapa yang berbasis-kotak-sibuk busybox-based. Itu tidak akan bekerja di csh tapi ini masalah csh.
Stéphane Chazelas
Karena \\ndigunakan di bagian pencarian, mengapa tidak digunakan \ndalam penggantian? yang pertama tampaknya menyiratkan yang terakhir ada. yaitu. kenapa tidak ini$ echo '1\n2'|sed 's/\\n/\n/g'
Dalam hal ini, \nadalah literal, menyiratkan bahwa itu muncul sebagai dua karakter: abackslash diikuti oleh n, dan bukan sebagai karakter baris baru. Oleh karena itu, dua backslash untuk membuat backslash menjadi harfiah dan kemudiann
unxnut
9

Karena Anda sudah memiliki sedjawaban portabel Anda , saya hanya akan menyebutkan bahwa sedjarang ada alat terbaik jika Anda perlu memanipulasi baris baru. Perl sangat mudah dibawa-bawa sed, diinstal secara default pada kebanyakan sistem * nix dan dapat menangani hal ini dengan sangat mudah:

printf '%s\n' 'aa\nbb' | perl -pe 's/\\n/\n/g'

Pilihan lain yang sangat portabel adalah awk:

printf '%s\n' 'aa\nbb' | awk  '{gsub("\\\\n","\n")};1'

Pada Solaris, ingatlah untuk menggunakan awk standar di / usr / xpg4 / bin, yang di / bin adalah yang historis dan tidak boleh digunakan untuk skrip baru.

terdon
sumber
Saya akan mengatakan awkmemiliki masalah portabilitas yang sama (Apakah saya sudah awktua awk, nawkatau gawk?). Sebenarnya, versi dalam kotak Solaris saya kurang gsub(). Pilihan saya di sini adalah untuk Perl ( perl -nlawe '...'mendekati perilaku otomatis awk).
arielCo
2
@arielCo: Untuk awkportabilitas, tetap menggunakan versi awkyang sesuai dengan POSIX dan hanya menggunakan fitur-fitur itu dan Anda harus baik-baik saja. Pada Solaris Anda akan menemukan satu sebagai /usr/xpg4/bin/awk.
Scrutinizer
@terdon bagaimana dengan ini echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'?
Avinash Raj
@arielCo sebenarnya, awk lebih portabel daripada perl. Pendekatan awk kedua saya yang tidak digunakan gsub()harus bekerja di mana-mana. Bahkan busybox memiliki awk.
terdon
1
gsub () adalah POSIX (gsub, ditambahkan dalam SVR3.1, POSIX awk didasarkan pada SVR4 dengan beberapa tambahan, lihat manual gawk untuk informasi lebih lanjut), gensub () adalah ekstensi GNU. Awk asli masih ditemukan sebagai / bin / awk di Solaris, tidak mendukung dukungan gsub (), tetapi juga tidak mendukung FS multi-karakter.
Stéphane Chazelas
1

Jika Holdspace kosong Anda juga dapat melakukan:

sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'

... tetapi jawaban uxnut sudah lebih cepat dan lebih sederhana, sehingga Anda dapat menerimanya sesuka Anda.

Kemungkinan asing lainnya:

INPUT | sed -n l | while read v ; do printf "${v%?}" ; done

Tapi waspadalah, ^ yang menerjemahkan semua lompatan \backslash C-style standar - seperti \backspace, \return, \00oktal, dan apa pun yang Anda miliki.

mikeserv
sumber
0

Dengan gnu sedyang berikut ini juga berfungsi:

gsed -n -e 'H;${x;s/\\n/\n/g;p;}'
Dirk Hoffmann
sumber
-2

Anda memerlukan solusi dalam sed, dan itu sudah diberikan di bawah ini. Tapi saya ingin menambahkan kemungkinan lain bahwa IMHO lebih mudah dan lebih cepat,

tr -d "\n"
jpmuc
sumber
1
apa fungsinya? hapus semua baris baru dari input?
mikeserv
Ya, itulah yang dilakukannya
jpmuc
5
tapi kenapa? apa hubungannya dengan pertanyaan itu?
mikeserv
1
Ini hanya menghilangkan "\ n" ketika pertanyaannya adalah bertanya bagaimana cara mengganti string "\ n" dengan baris baru yang sebenarnya.
Spuder