sed gagal menghapus karakter baris baru

12

Saya telah menggunakan sedbeberapa waktu tetapi ini adalah kekhasan yang saya alami , yang tidak bisa saya selesaikan.

Biarkan saya menjelaskan masalah saya dengan kasus yang sebenarnya.


Adegan # 1

printf "ls" | xclip -selection clipboard
echo "ls" | xclip -selection clipboard

Pada perintah pertama, saya menyalurkan printfoutput ke xclipsehingga disalin ke clipboard. Sekarang, printftidak seperti echotidak memasukkan baris baru di akhir secara default. Jadi, jika saya menempelkan konten ini ke terminal, lsperintah yang disalin tidak berjalan secara otomatis.

Di baris kedua, ada baris baru di bagian akhir, jadi menempelkan konten clipboard juga menghasilkan jalannya perintah di clipboard.

Ini tidak diinginkan untukku. Jadi, saya ingin menghapus baris baru menggunakan sed, tetapi gagal, seperti yang dijelaskan dalam adegan di bawah ini.

Adegan # 2

echo "ls" | sed -r 's/\n//g' | xclip -selection clipboard

Konten di clipboard masih berisi baris baru. Ketika saya menempelkannya ke terminal, perintah secara otomatis berjalan.

Saya juga mencoba menghapus karakter carriage return \r. Tapi nada. Sepertinya saya kehilangan sesuatu yang sangat penting / mendasar di sini.

shivams
sumber

Jawaban:

16

sed\nbatas pada baris baru - mereka selalu dihapus pada input dan dimasukkan kembali pada output. Tidak pernah ada \nkarakter ewline dalam sedruang pola yang tidak terjadi sebagai hasil edit yang Anda buat. Catatan: dengan pengecualian dari GNU sed's -zmodus ...

Cukup gunakan tr:

echo ls | tr -d \\n | xclip -selection clipboard

Atau, lebih baik lagi, lupakan sedsemuanya:

printf ls | xclip -selection clipboard
mikeserv
sumber
Ini akan menghapus semua baris baru, sering kali tidak diinginkan dalam generate-text | xclipkasus ini. Jawaban ini hanya menghilangkan baris baru terakhir.
Tom Hale
7

Banyak alat pemrosesan teks, termasuk sed, beroperasi pada konten baris, tidak termasuk karakter baris baru. Hal pertama yang dilakukan saat memproses sebuah baris adalah menghapus baris baru di bagian akhir, kemudian mengeksekusi perintah dalam skrip, dan menambahkan baris baru saat mencetak. Jadi, Anda tidak akan dapat menghapus baris baru dengan sed.

Untuk menghapus semua baris baru, Anda dapat menggunakan tr:

echo "ls" | tr -d '\n' | xclip

Gilles 'SANGAT berhenti menjadi jahat'
sumber
4

Anda dapat mengganti baris baru dengan sed dengan opsi -z .

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

Halaman manual sed:

-z, --null-data memisahkan baris dengan karakter NUL

JSON C11
sumber
Ini akan menghapus semua baris baru, yang umumnya tidak diinginkan dalam | xclipkasus ini.
Tom Hale
2

Jika Anda hanya menempatkan perintah di clipboard

echo -n "ls " | xclip -selection clipboard

Jika Anda juga perlu membuat transformasi yang lebih kompleks,

echo "ls  " | perl -pe 's/\n//' | xclip -selection clipboard
Joao
sumber
Hmm. Solusi halus. Saya kira ini mungkin saatnya untuk beralih ke perl atau python untuk regex.
shivams
3
@shivams - perldan pythonkeduanya jauh lebih lambat daripada yang sedbisa digunakan dengan benar. Belajar menggunakannya dengan benar adalah kuncinya.
mikeserv
@ mikeserv - Saya setuju; spesial untuk oneliner sed luar biasa. Jika transformasi akan menjadi lebih kompleks, maka saya lebih suka perl / python / gawk.
JJoao
1
@JJoa: Preferensi Anda adalah milik Anda sendiri, tetapi seddapat melakukan jauh lebih banyak daripada hanya menangani satu-liner Anda, dan kemungkinan bisa melakukannya lebih cepat daripada alat-alat lain yang Anda sebutkan.
mikeserv
1
@ mikeserv - sekali lagi, saya setuju dengan Anda. Beberapa tahun yang lalu saya memiliki sistem terjemahan EN-PT yang ditulis dalam sed (20000 s /.../.../), dihasilkan oleh sed! Dan itu berhasil! Kemudian menjadi Perl, untuk memiliki array, hash, fungsi, paket dan CPAN.
JJoao
1

Untuk menghapus hanya baris baru terakhir , pipa melalui:

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

sedtidak akan menambahkan \0ke akhir aliran jika pembatas diatur ke NULvia -z, sedangkan untuk membuat file teks POSIX (didefinisikan berakhir di a \n), selalu akan menghasilkan akhir \ntanpa -z.

Misalnya:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender

Dan untuk membuktikan tidak ada yang NULditambahkan:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72                        foo.bar

Untuk menghapus beberapa baris baru , ikuti :

sed -Ez '$ s/\n+$//'
Tom Hale
sumber