sagen wir, ich habe eine SQL.txt
select * from table1;
select a,b,c from table2 where a=1;
Wie kann ich mit dem Befehl den Tabellennamen filterncat SQL.txt|grep
Meine erwartete Ausgabe ist:
table1
table2
Ich bin ein Neuling in Sachen grep
Command und bin für jede Hilfe dankbar. Danke.
Aktualisieren
Ich möchte wissen, wie ich den regulären Ausdruck im grep
Befehl anwende.
für diesen Fall kann ich den regulären Ausdruck schreiben: from (.*?)
. Das Problem ist, dass ich nicht weiß, wie ich reguläre Ausdrücke mit grep verwenden soll
Antwort1
Grep nimmt einfach ein Muster und eine Datei als Argumente. Wie in erklärt man grep
:
GREP(1) User Commands GREP(1)
NAME
grep, egrep, fgrep - print lines that match patterns
SYNOPSIS
grep [OPTION...] PATTERNS [FILE...]
grep [OPTION...] -e PATTERNS ... [FILE...]
grep [OPTION...] -f PATTERN_FILE ... [FILE...]
DESCRIPTION
grep searches for PATTERNS in each FILE. PATTERNS is one or more
patterns separated by newline characters, and grep prints each line
that matches a pattern. Typically PATTERNS should be quoted when grep
is used in a shell command.
Das allgemeine Format ist also grep 'regex' file
. Um Ihren Beispiel-Regex zu verwenden, würden Sie Folgendes tun:
grep 'from (.*?)' file
Das funktioniert jedoch nicht, da grep
verwendetGrundlegende reguläre Ausdrücke(BRE), die Klammern nicht als Sonderzeichen behandeln 1 und den nicht-gierigen Operator (finde die kürzeste Übereinstimmung) nicht verstehen *?
. Was Sie eigentlich wollen, ist:
grep 'from [^[:blank:]]' file
Dabei wird die BRE-Zeichenklasse verwendet [[:blank:]]
, abernegiertes mit ^
( [^[:blank:]]
), so dass es jetzt auf alle Zeichen außer Leerzeichen passt. Dies ist jedoch immer noch nicht das, was Sie brauchen, da grep
die gesamte Übereinstimmung zurückgegeben wirdLinieund nicht nur den Teil der Zeile, der übereinstimmte.
Wenn Sie GNU haben grep
(die Standardeinstellung unter Linux), haben Sie die -o
Option, grep
nur den übereinstimmenden Teil zurückzugeben:
$ grep -o 'from [^[:blank:]]*' file
from table1;
from table2
Natürlich ist das immer noch nicht das, was Sie brauchen, da es einen zusätzlichen from
, ein Leerzeichen und ein Ende ;
in einem davon gibt. Noch einmal, wenn Sie GNU haben grep
, können Sie PCRE (Perl Compatible Regular Expressions) verwenden, das unterstütztUmschauungen:
$ grep -oP '(?<=from )\w+' file
table1
table2
Hier -o
weist das an grep
, nur den passenden Teil zurückzugeben und das -P
aktiviert die PCRE-Unterstützung. Das (?<=from )
wird alspositiver Blick zurückund bedeutet „Nächsten Teil nur abgleichen, wenn der vorherige Teil übereinstimmt from
“. Schließlich \w
gibt es eine spezielle PCRE-Klasse, die „Wortzeichen“ abgleicht: Buchstaben, Zahlen und _
(und ein bisschen mehr, wenn Unicode verwendet wird). Wie in erklärt man perlre
:
\w [3] Match a "word" character (alphanumeric plus "_", plus
other connector punctuation chars plus Unicode
marks)
PCREs haben auch die raffinierte \K
Funktion. Dies ist wie ein Lookbehind, bedeutet aber im Grunde „alles ignorieren, was bis hierher übereinstimmt“. Damit können wir den obigen regulären Ausdruck wie folgt vereinfachen:
$ grep -oP 'from \K\w+' file
table1
table2
Antwort2
Mit AWK-Befehl ohne Piping versucht, getestet und funktionierte einwandfrei
awk '{for(i=1;i<=NF;i++){if($i ~ /^table/){gsub(";","",$i);print $i}}}' file
Ausgabe
table1
table2