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
$N
karakter diikuti oleh foo
diikuti oleh 0 ke $N
karakter.
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 grep
menjadi GNU grep
, kami menggunakan find
untuk mencari file secara rekursif ( -r
tindakan 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 $N
ke 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 grep
kasus ini, foo
diikuti oleh yang lain .{0,$N}
dan akhirnya cocokkan barang lama dengan malas sampai akhir baris ( .*?$
).
- Kami menggantinya dengan
$ARGV:$1
. $ARGV
adalah variabel magis yang menyimpan nama file saat ini sedang dibaca. $1
adalah apa yang cocok dengan orangtua: konteks dalam kasus ini.
- Pertandingan malas di kedua ujung diperlukan karena pertandingan serakah akan memakan semua karakter sebelum
foo
tanpa 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.