Bagaimana saya bisa mendapatkan direktori untuk baris yang berisi "Foo", tetapi hanya mendapatkan kecocokan ketika baris berikutnya juga berisi "Bar"?
Bagaimana saya bisa mendapatkan direktori untuk baris yang berisi "Foo", tetapi hanya mendapatkan kecocokan ketika baris berikutnya juga berisi "Bar"?
Jawaban:
@ warl0ck menunjuk saya ke arah yang benar dengan pcregrep, tetapi saya berkata "berisi", bukan "adalah", dan saya bertanya tentang direktori, bukan file.
Ini sepertinya bekerja untuk saya.
pcregrep -rMi 'Foo(.*)\n(.*)Bar' .
Grep sendiri sepertinya tidak mendukungnya, gunakan pcregrep sebagai gantinya:
Foo
Bar
Foo
abc
pcregrep -M "Foo\nBar" file
Punya:
Foo
Bar
Foodan Barakan terdiri dari seluruh lini.
Dengan sedskrip:
#!/bin/sed -nf
/^Foo/{
h # put the matching line in the hold buffer
n # going to nextline
/^Bar/{ # matching pattern in newline
H # add the line to the hold buffer
x # return the entire paragraph into the pattern space
p # print the pattern space
q # quit the script now
}
}
Untuk menggunakannya:
chmod +x script.sed
printf '%s\n' * | ./script.sed
Di printfsini menampilkan semua file dalam direktori saat ini pada setiap baris, dan meneruskannya ke sed.
Catatan : ini disortir berdasarkan urutan abjad.
Info lebih berguna pattern spacedan hold space DI SINI .
grymoire.com memiliki hal-hal yang sangat baik tentang shellpemrograman.
h, n, H, x, p, qartinya? Sangat menarik.
pattern space& hold space: grymoire.com/Unix/Sed.html#uh-56 atau dalam bahasa Perancis commentcamarche.net/faq/9536-sed-introduction-a-sed-part-i
Hanya menggunakan grep, Anda bisa membuat pipa berikut:
grep -A1 'Foo' input_file | grep -B1 'Bar' | grep 'Foo'
Yang pertama grepakan mendapatkan semua baris yang berisi Fooserta baris setelah pertandingan. Lalu kami mendapatkan garis yang berisi Barserta garis sebelum pertandingan, dan akhirnya mengekstrak garis dari output yang berisi ini Foo.
EDIT: Seperti yang ditunjukkan oleh manatwork , ada beberapa kasus bermasalah yang harus diperhatikan. Meskipun tantangan yang menarik, karena grepfungsionalitas yang berorientasi pada garis, solusi apa pun yang ada kemungkinan adalah 'retas' dan Anda mungkin lebih baik menggunakan sesuatu seperti pcregrepyang lebih cocok untuk tugas yang sedang dihadapi.
find . -name '*.txt' | xargs grep -A1 'Foo' | grep -B1 'Bar'
Sementara saya lebih suka menggunakan solusi Nathan pcregrep, berikut adalah solusi hanya menggunakan grep
grep -o -z -P 'Foo(.*)\n(.*)Bar' file
Penjelasan opsi:
-ohanya mencetak bagian yang cocok. Diperlukan sejak dimasukkannya -zakan mencetak seluruh file (kecuali ada \ 0 di suatu tempat)-z Perlakukan input sebagai satu set garis, masing-masing diakhiri dengan byte nol (karakter ASCII NUL) alih-alih baris baru.-P sintaks perl regex EDIT: Versi ini mencetak seluruh baris yang cocok
grep -o -P -z '(.*)Foo(.*)\n(.*)Bar(.*)' file
-z. Beberapa "(. *)" Sebelum dan sesudah seluruh ekspresi akan membuatnya menampilkan seluruh baris yang cocok. Untuk saat ini substring sebelum "Foo" dan setelah "Bar" tidak ditampilkan.
Dengan awk:
awk '/bar/ && prev != "" {print FILENAME ": " prev "\n" FILENAME ": " $0}
/foo/ {prev=$0; next}
{prev=""}' file1...
(catatan umum tentang batasan awk: berhati-hatilah bahwa jika beberapa nama file mungkin berisi "=" karakter, Anda harus meneruskannya sebagai ./filenameganti filenameawk)