operator grep “+” tidak berfungsi

31

Ini

ls -l /var/log | awk '{print $9}' | grep "^[a-z]*\.log."

output ini:

alternatives.log.1
alternatives.log.10.gz
alternatives.log.2.gz
alternatives.log.3.gz
alternatives.log.4.gz
alternatives.log.5.gz
alternatives.log.6.gz
alternatives.log.7.gz
alternatives.log.8.gz
alternatives.log.9.gz
apport.log.1
apport.log.2.gz
apport.log.3.gz

tapi ini:

ls -l /var/log | awk '{print $9}' | grep "^[a-z]+\.log."

tidak menghasilkan apa-apa.

Mengapa? Saya baru saja berubah *menjadi +. Bukankah ini mirip? Operator +hanya perlu setidaknya satu pertandingan, dan *nol atau lebih.

Marko
sumber

Jawaban:

36

Ini karena grep(tanpa argumen) hanya berfungsi dengan ekspresi reguler standar. +adalah bagian dari ekspresi reguler yang diperluas, jadi untuk menggunakannya, Anda perlu menggunakan grep -Eatau egrep:

ls -l /var/log | awk '{print $9}' | grep -E "^[a-z]+\.log."

Anda juga bisa melakukan ini jika Anda tidak ingin menggunakan ekspresi reguler yang diperluas:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."
MiJyn
sumber
Terima kasih. Saya sekarang tentang solusi itu, tetapi saya bertanya-tanya mengapa "+" tidak bekerja. Sekarang saya tahu. Terima kasih lagi.
Marko
11

Untuk menguraikan jawaban MiJyns, "karakter khusus" seperti + berfungsi di regex standar juga, tetapi Anda perlu menghindarinya dengan backslash. Anda bisa mengatakan, ekspektasi default dibalik antara regex standar dan diperpanjang:

Di regex standar, karakter secara harfiah sesuai dengan standar. Misalnya, dalam grep "ab+"+ adalah + literal. Regex misalnya akan menemukan "ab + ab", tetapi tidak "abbbb". Untuk menggunakan "makna khusus" +, Anda harus menghindarinya. Jadi grep "ab\+"akan menemukan "abbb", tetapi bukan "ab + ab" lagi. Karena dalam contoh terakhir, + ditafsirkan sebagai kuantifier "satu atau banyak dari itu", dalam hal itu "satu atau banyak b".

Dalam regex diperpanjang itu justru sebaliknya. Di sini, Anda perlu melarikan diri dari "karakter khusus" untuk diperlakukan secara harfiah. Jadi grep -E "ab+"menemukan "abbb", tetapi bukan "ab + ab". Jika Anda keluar dari +, itu cocok secara harfiah. Jadi grep -E "ab\+"menemukan "ab + ab", tetapi tidak "abbb".

Henning Kockerbeck
sumber
1
Apa kekacauan warisan ... ;-) seperti sulap dan supermagic re in vim. Urgh. Harga yang harus dibayar untuk kompatibilitas ke belakang ...
Rmano