Bisakah GNU Grep menghasilkan grup yang dipilih?


47

Apakah mungkin untuk menggunakan GNU grep untuk mendapatkan grup yang cocok dari ekspresi?

Contoh:

echo "foo 'bar'" | grep -oE "'([^']+)'"

Yang akan menghasilkan "'bar'". Tetapi saya hanya ingin mendapatkan "bar", tanpa harus mengirimkannya melalui grep sekali lagi (mis. Dapatkan grup yang cocok). Apakah itu mungkin?

Jawaban:


50

Anda bisa menggunakannya seduntuk ini. Pada BSD sed:

echo "foo 'bar'" | sed -E "s/.*'([^']+)'.*/\\1/"

Atau, tanpa -Eopsi:

sed "s/.*'\([^']\+\)'.*/\1/"

Ini tidak berfungsi untuk input multiline. Untuk itu Anda perlu:

sed -n "s/.*'\([^']\+\)'.*/\1/p"

Terima kasih, sudah lupa tentang sed. Tetapi untuk memperjelas, sed tidak mengambil argumen -E ..
Torandi

Hm, itu ada di mesin saya (Mac OS X). Setelah diperiksa lebih lanjut, di halaman manual: "Opsi -E, -a dan -i adalah ekstensi FreeBSD yang tidak standar dan mungkin tidak tersedia pada sistem operasi lain."
jtbandes

1
-r sepertinya itu untukku.
Torandi

1
@jtbandes: Anda tidak memerlukan fitur tambahan untuk ekspresi ini .. Saya hanya membutuhkan 3 karakter untuk ( ) +digunakan \( \) \+: Ini sama saja:sed "s/.*'\([^']\+\)'.*/\1/"
Peter.O

2
Ini tidak berfungsi untuk input multiline. Untuk itu Anda perlu: sed -n "s/.*'\([^']\+\)'.*/\1/p"
phreakhead

28

Meskipun grep tidak dapat menampilkan grup tertentu, Anda dapat menggunakan lookahead dan di belakang pernyataan untuk mencapai apa yang Anda inginkan:

echo "foo 'bar'" | grep -Po "(?<=')[^']+(?=')"


8
grep -Ptidak tersedia di semua platform. Tetapi jika ya, menggunakan lookahead / belakang adalah cara yang sangat bagus untuk menyelesaikan masalah.
Sébastien

1
Apakah grep cerdas dengan pernyataan melihat ke belakang? Bagaimana kinerjanya dengan tampilan panjang? Apakah ini mengintegrasikan tampilan-belakang ke dalam semacam "pohon akhiran" dengan sisa regex?
Ross Rogers

3

Anda dapat menggunakan \Kuntuk mengatur ulang dan membuang teks pertandingan tangan kiri bersama dengan lookahead yang tidak ditambahkan ke teks pertandingan:

$ echo "foo 'bar'" | grep -oP "'\K[^']+(?=')"
bar

Hanya GNU grep.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.