Jika Anda memenuhi syarat kata yang berarti urutan 1 atau lebih karakter tidak kosong maka jawabannya pasti ya, dan itu sangat sederhana dilakukan juga. Ini karena [[:blank:]]*
dan [^[:blank:]]*
merupakan pelengkap boolean dan - asalkan semua karakter dalam sebuah string lengkap - [[:blank:]]*
U [^[:blank:]]*
dapat menggambarkan string apa pun yang mungkin dengan cara yang sama .*
.
Jika karakter yang tidak lengkap atau urutan byte yang tidak valid ada dalam suatu string, tidak satu pun dapat berhasil menggambarkannya secara langsung - seperti yang kadang-kadang dapat terjadi ketika menafsirkan string dalam pengkodean yang salah. Untuk memastikan karakter lengkap per byte dalam string apa pun, C locale dapat dipaksa seperti:
LC_ALL=C sed ...
... yang akan menghindari masalah apa pun yang menggambarkan string dari kepala ke ekor dengan pola semua termasuk seperti .*
atau([ ]*[^ ]*)*
Sebuah pola yang saling melengkapi dapat diulang sebanyak yang diperlukan dari kiri ke kanan sepanjang tali untuk mendarat pada kemungkinan yang terakhir terjadi tanpa ada kerusakan pada pola. Ini, secara pasti, adalah bahasa reguler.
BRE:
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*/\2/'
SEBELUM:
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*/\2/'
Kedua versi ini masih akan mencetak garis kosong, dan ini karena *
bintang Kleene cocok dengan nol atau lebih kemunculan pola. Pertama-tama cocok dengan nol atau lebih bukan karakter kosong, lalu nol atau lebih karakter kosong, lalu nol atau lebih dari kecocokan yang dikelompokkan hingga cocok dengan string secara keseluruhan.
Setelah mencocokkan semua ini, keajaiban terjadi dalam penggantian - referensi dikembalikan oleh kelompok \1
dan \2
merupakan kejadian terakhir masing-masing. Jadi ketika penggantian dilakukan semua string diganti dengan hanya kejadian terakhir pada garis nol atau lebih bukan karakter kosong - atau subkelompok \2
.
Tentu saja ini berfungsi untuk string apa pun - bahkan yang kosong - yang berarti kedua formulir akan mencetak karakter baris baru untuk baris yang hanya berisi karakter kosong atau tidak sama sekali. Untuk mengatasinya ada beberapa hal yang dapat Anda lakukan, tetapi pertama-tama mari kita buat kelas karakter sedikit lebih mudah untuk diketik:
b='[:blank:]'
Sekarang, untuk mencetak hanya jika satu baris berisi satu atau lebih karakter tidak kosong yang dapat Anda lakukan:
BRE:
sed -n "s/\(\([^$b]*\)[$b]*\)*/\2/;/./p"
SEBELUM:
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*/\2/p"
- Kasur BRE - penggantian selalu dilakukan dan hanya ruang pola dengan setidaknya satu karakter tersisa yang dicetak.
- Kasing ERE - penggantian hanya dilakukan pada ruang pola yang berisi setidaknya satu char tidak kosong.
Formulir mana pun akan bekerja dengan metode mana pun - selama sintaksinya benar.
The -n
menonaktifkan saklar otomatis mencetak ruang pola, dan p
bendera ke s///
ubstitution atau /
alamat /
perintah mencetak hasil-hasilnya hanya jika berhasil.
Logika yang sama ini dapat diterapkan untuk mendapatkan {num}
kejadian apa pun , juga, seperti:
BRE:
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*/\2/p"
SEBELUM:
sed -En "s/([$b]*([^$b]+)){num}.*/\2/p"
... di mana num
di kedua regexps dapat diganti dengan angka untuk hanya mencetak {num}
kemunculan yang ditentukan dari urutan karakter yang tidak kosong. Bentuk yang sedikit berbeda digunakan di sini untuk memastikan penghitungan tidak condong untuk memimpin spasi dalam string.
Perhatikan bahwa -E
sakelar ERE untuk sed
didukung dalam versi BSD dan GNU, meskipun belum sintaks standar POSIX.
sed
?