Dengan GNU grep:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
Penjelasan:
-o => Cetak hanya apa yang Anda cocokkan
-P => Gunakan ekspresi reguler Perl-style
- Regex mengatakan pertandingan 0 ke
$Nkarakter diikuti oleh foodiikuti oleh 0 ke $Nkarakter.
Jika Anda tidak memiliki GNU grep:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
Penjelasan:
Karena kita tidak bisa lagi mengandalkan grepmenjadi GNU grep, kami menggunakan finduntuk mencari file secara rekursif ( -rtindakan GNU grep). Untuk setiap file yang ditemukan, kami menjalankan cuplikan Perl.
Switch Perl:
-n Baca file baris demi baris
-l Hapus baris baru di akhir setiap baris dan pasang kembali saat mencetak
-e Perlakukan string berikut sebagai kode
Cuplikan Perl pada dasarnya melakukan hal yang sama dengan grep. Dimulai dengan mengatur variabel $Nke jumlah karakter konteks yang Anda inginkan. The BEGIN{}sarana ini dijalankan hanya sekali pada awal eksekusi tidak sekali untuk setiap baris dalam setiap file.
Pernyataan yang dieksekusi untuk setiap baris adalah untuk mencetak baris jika substitusi regex berfungsi.
Regex:
- Cocokkan barang lama dengan malas 1 di awal baris (
^.*?) diikuti oleh .{0,$N}seperti dalam grepkasus ini, foodiikuti oleh yang lain .{0,$N}dan akhirnya cocokkan barang lama dengan malas sampai akhir baris ( .*?$).
- Kami menggantinya dengan
$ARGV:$1. $ARGVadalah variabel magis yang menyimpan nama file saat ini sedang dibaca. $1adalah apa yang cocok dengan orangtua: konteks dalam kasus ini.
- Pertandingan malas di kedua ujung diperlukan karena pertandingan serakah akan memakan semua karakter sebelum
footanpa gagal untuk mencocokkan (karena .{0,$N}diizinkan untuk mencocokkan nol kali).
1 Artinya, lebih memilih untuk tidak mencocokkan apa pun kecuali ini akan menyebabkan kecocokan keseluruhan gagal. Singkatnya, sesuaikan karakter sesedikit mungkin.