Mit GNU grep
:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
Erläuterung:
-o
=> Nur das drucken, was du gefunden hast
-P
=> Verwenden Sie reguläre Ausdrücke im Perl-Stil
- Der reguläre Ausdruck besagt, dass
$N
Zeichen foo
mit 0 gefolgt von $N
Zeichen mit 0 übereinstimmen .
Wenn Sie kein GNU haben grep
:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
Erläuterung:
Da wir uns nicht mehr darauf verlassen können grep
, GNU zu sein grep
, find
suchen wir rekursiv nach Dateien (die -r
Aktion von GNU grep
). Für jede gefundene Datei führen wir das Perl-Snippet aus.
Perl-Schalter:
-n
Lesen Sie die Datei Zeile für Zeile
-l
Entfernen Sie den Zeilenumbruch am Ende jeder Zeile und setzen Sie ihn beim Drucken wieder ein
-e
Behandeln Sie die folgende Zeichenfolge als Code
Das Perl-Snippet macht im Wesentlichen dasselbe wie grep
. Zunächst wird eine Variable $N
auf die Anzahl der gewünschten Kontextzeichen gesetzt. Die BEGIN{}
Mittel , dies wird nur einmal zu Beginn der Ausführung nicht einmal für jede Zeile in jeder Datei ausgeführt.
Die Anweisung, die für jede Zeile ausgeführt wird, gibt die Zeile aus, wenn die Regex-Ersetzung funktioniert.
Der Regex:
- Ordnen Sie ein beliebiges altes Ding faul 1 am Anfang der Zeile (
^.*?
) zu, gefolgt von .{0,$N}
wie im grep
Fall, foo
gefolgt von einem anderen .{0,$N}
und ordnen Sie schließlich ein beliebiges altes Ding faul bis zum Ende der Zeile ( .*?$
) zu.
- Wir ersetzen dies durch
$ARGV:$1
. $ARGV
ist eine magische Variable, die den Namen der aktuell gelesenen Datei enthält. $1
Dazu passten die Eltern: der Kontext in diesem Fall.
- Die faulen Übereinstimmungen an beiden Enden sind erforderlich, da eine gierige Übereinstimmung alle Zeichen zuvor frisst,
foo
ohne dass eine Übereinstimmung fehlschlägt (da .{0,$N}
null Übereinstimmungen zulässig sind).
1 Das heißt, passen Sie lieber nichts an, es sei denn, dies würde dazu führen, dass die Gesamtübereinstimmung fehlschlägt. Kurz gesagt, stimmen Sie mit so wenigen Zeichen wie möglich überein.