Bagaimana mencocokkan spasi putih di sed?

218

Bagaimana saya bisa mencocokkan spasi putih di sed? Dalam data saya, saya ingin mencocokkan semua 3+ karakter spasi putih berikutnya (ruang tab) dan menggantinya dengan 2 spasi. Bagaimana ini bisa dilakukan?

Peter Smit
sumber

Jawaban:

226

Kelas karakter \sakan cocok dengan karakter spasi <tab>dan <space>.

Sebagai contoh:

$ sed -e "s/\s\{3,\}/  /g" inputFile

akan mengganti setiap urutan setidaknya 3 spasi putih dengan dua spasi.


KETERANGAN : Untuk kepatuhan POSIX, gunakan kelas karakter [[:space:]]alih-alih \s, karena yang terakhir adalah ekstensi sed GNU. Lihat spesifikasi POSIX untuk sed dan BRE

mrucci
sumber
5
aha! Itu saklar -e yang hilang yang membuatku.
sequoia mcdowell
25
Saya juga harus menambahkan '-r' yang memungkinkan regex yang diperluas untuk membuat sed mengenali 'sebagai' ruang.
HUB
39
Dengan Apple sedsaya harus menggunakan [[:space:]]karena \stidak bekerja untuk saya. Mungkin \sadalah GNU sed ekstensi?
Jared Beck
2
@JaredBeck terima kasih, kehabisan ide mengapa regex sederhana saya tidak berfungsi .. Ini lumpuh, saya pikir \ adalah regex extended standar. Juga -r tidak bekerja dan -E tidak berjongkok
Karthik T
3
Alih-alih [[:space:]satu dapat menggunakan [[:blank:]]yang tidak cocok dengan tab dan spasi horisontal saja (tetapi tidak ada baris baru, tab vertikal dll).
stefanct
67

Ini berfungsi pada MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
beberapa ide
sumber
2
Anda tahu apakah ini bekerja di semua distro Linux?
amfibi
2
Tidak secara umum, sed GNU tidak akan memiliki -E. Dari halaman manual BSD sed: "Opsi -E, -a dan -i adalah ekstensi FreeBSD yang tidak standar dan mungkin tidak tersedia pada sistem operasi lain."
Brad Koch
1
Mengapa Anda memerlukan flag -E, untuk operator +? Sebagian besar ekspresi mungkin akan baik-baik saja dengan * sebagai gantinya, maka ini akan bekerja pada platform lain.
Samuel
5
@Samuel Jika Anda menggunakan *, regex akan cocok dengan nol atau lebih banyak ruang, dan Anda akan mendapatkan spasi di antara setiap karakter, dan spasi di setiap ujung setiap baris. Jika Anda tidak memiliki flag -E, maka Anda ingin sed "s/[[:space:]]\+/ /g"mencocokkan satu atau lebih spasi.
jbo5112
1
FWIW, sed NetBSD mendukung -Ebendera juga.
mcandre
13

Beberapa versi sed yang lebih lama mungkin tidak dikenali sebagai token pencocokan spasi putih. Dalam hal ini Anda dapat mencocokkan urutan satu atau lebih spasi dan tab dengan '[XZ] [XZ] *' di mana X adalah spasi dan Z adalah tab.

Marnix A. van Ammers
sumber
1
Jadi untuk kebutuhan khusus di sini, dengan sed yang lebih tua, Anda dapat melakukan: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' inputfile di mana X adalah tab dan Z adalah spasi.
Marnix A. van Ammers
10
sed 's/[ \t]*/"space or tab"/'
Zac
sumber
2
Apakah ini dijamin berfungsi pada versi sedapa pun pada sistem apa pun? Jika tidak, mungkin perlu disebutkan di mana ini bekerja dengan cara yang sama dengan jawaban lainnya, supaya kita tahu keterbatasan dan di mana ini mungkin tidak memiliki hasil yang diinginkan.
Mokubai
2
RE ini yang saya gunakan untuk mencocokkan spasi putih. Ini lebih sederhana daripada kelas karakter hanya untuk mencocokkan tab atau ruang. Ini hanya menggunakan konvensi paling umum dari ekspresi reguler, sehingga harus bekerja di mana saja dengan implementasi fungsional ekspresi reguler.
Nate
3
Pada Mac 10.9.5 ini cocok dengan spasi dan 't'. Saya menggunakan Michael Douma di atas untuk mencocokkan karakter spasi (juga berfungsi dengan -e).
Formulir Kehidupan Asing
Tidak berfungsi dengan baik pada sistem SUSE saya. Ini cocok dengan tempat pertama pada baris di mana ada nol atau lebih banyak ruang, yang sebelum karakter pertama. Saya ragu itu adalah fungsi yang dimaksudkan, dan tentu saja bukan kasus penggunaan yang diminta. Saya yakin Anda ingin mengubah '*' untuk '\ +' (atau '\ {3, \}' per pertanyaan) dan mungkin meletakkan ag di akhir perintah sed untuk mencocokkan semua kemunculan pola. Mengganti [\ t] dengan [[: space:]] juga mungkin diinginkan, jika ada hal lain untuk spasi putih di baris tersebut.
jbo5112