Folgendes in einer meiner Shell-Funktionen haben:
function _process () {
awk -v l="$line" '
BEGIN {p=0}
/'"$1"'/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
}
Wenn also as aufgerufen wird _process $arg
, $arg
wird as übergeben $1
und als Suchmuster verwendet. Es funktioniert auf diese Weise, weil sich die Schale $1
anstelle des awk-Musters ausdehnt ! Auch l
können innerhalb awk - Programm verwendet werden, wobei erklärt mit -v l="$line"
. Alles gut.
Ist es auf die gleiche Weise möglich, Suchmuster als Variable anzugeben?
Folgendes wird nicht funktionieren,
awk -v l="$line" -v search="$pattern" '
BEGIN {p=0}
/search/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
, as awk wird nicht /search/
als Variable interpretiert , sondern wörtlich.
if (p) ...
$0 ~ pattern
, und es funktioniert nicht, aber/'"$1"'/
damit funktioniert es !? : O$line
, wie Muster abgerufen werden. Die Mustersuche wird an der Ausgabe von durchgeführtwhois $line
,$line
die aus einer Datei in einem WHILE DO-Block stammt.$line
- machen Sie es in Ihrer Frage für die richtige Formatierung.Hat ein Problem darin, dass
awk
die ANSI C-Escape-Sequenzen (wie\n
für Newline,\f
für Form Feed,\\
für Backslash und so weiter) in erweitert$1
. Daher wird es zu einem Problem, wenn$1
Zeichen mit umgekehrten Schrägstrichen enthalten sind, wie es in regulären Ausdrücken üblich ist (ab GNUawk
4.2 sind Werte, die mit@/
und enden/
, ebenfalls ein Problem ). Ein anderer Ansatz, der nicht unter diesem Problem leidet, besteht darin, es zu schreiben:Wie schlimm es wird, hängt von der
awk
Implementierung ab.Alle
awk
s funktionieren jedoch für gültige Escape-Sequenzen gleich:(Inhalt des übergebenen
$a
Zustandes)(
\\
geändert in\
und\b
geändert in ein Backspace-Zeichen).quelle
\d{3}
drei Ziffern finden würde, würde das nicht wie erwartet funktionieren, wenn ich Sie gut verstehe?\d
die es sich nicht um eine gültige C-Escape-Sequenz handelt, hängt dies von Ihrerawk
Implementierung ab (awk -v 'a=\d{3}' 'BEGIN{print a}'
zur Überprüfung ausführen ). Aber für\` or
\ b, yes definitely. (BTW, I don't know of any awk implementations that understands
\ d 'als eine Ziffer).\d' treated as plain
d 'd {3}, also hätte ich in diesem Fall wohl ein Problem?ENVIRON["PATTERN"]
derPATTERN
Umgebungsvariablen übereinstimmen. Wenn Sie eine Shell-Variable verwenden möchten, müssen Sie sie zuerst exportieren (export variable
) oder dieENV=VALUE awk '...ENVIRON["ENV"]'
env-var-Übergabesyntax wie in meiner Antwort verwenden.Versuchen Sie etwas wie:
quelle
/regex/
beim Auffinden von Mustern, könnte dies eine gute Lösung sein. Ich werde es versuchen.Nein, aber Sie können das Muster einfach in die doppelte Anführungszeichenfolge interpolieren, die Sie an awk übergeben:
Beachten Sie, dass Sie jetzt das doppelte Anführungszeichen awk-Literal umgehen müssen, dies jedoch immer noch am einfachsten zu bewerkstelligen ist.
quelle
$pattern
Leerzeichen enthalten sind? Mein Beispiel von oben funktioniert, da $ 1 mit doppelten Anführungszeichen "$ 1" geschützt ist, aber nicht sicher ist, was in Ihrem Fall passiert.'
, schützt dann die$1
doppelten Anführungszeichen und greift dann eine weitere Zeichenfolge in einfachen Anführungszeichen für die zweite Hälfte des awk-Programms an. Wenn ich das richtig verstehe, sollte dies genau den gleichen Effekt haben wie das Schützen der$1
äußeren einfachen Anführungszeichen - awk sieht niemals die doppelten Anführungszeichen, die Sie um sie setzen.$pattern
enthält^/ {system("rm -rf /")};
, dann sind Sie in großen Schwierigkeiten.Sie können die Funktion eval verwenden, die in diesem Beispiel die Variable nets auflöst, bevor awk ausgeführt wird.
quelle