Wie kann ich grep
Registerkarte ( \t ) in Dateien auf der Unix-Plattform?
Antworten
Zu viele Anzeigen?Eine andere Möglichkeit, den Tabulator buchstäblich innerhalb des Ausdrucks einzufügen, ist die Verwendung des weniger bekannten $'\t'
Zitat in Bash:
grep $'foo\tbar' # matches eg. 'foo<tab>bar'
(Beachten Sie, dass Sie bei der Suche nach festen Zeichenketten diese Funktion auch mit -F
Modus).
Manchmal kann die Verwendung von Variablen die Notation etwas lesbarer und übersichtlicher machen:
tab=$'\t' # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id" # matches eg. `bob2<tab>323`
Es gibt grundsätzlich zwei Möglichkeiten, dieses Problem anzugehen:
-
( Empfohlen ) Verwenden Sie die von grep(1) unterstützte Syntax für reguläre Ausdrücke. Das moderne grep(1) unterstützt zwei Formen der POSIX 1003.2 Regex-Syntax: grundlegend (veraltete) REs, und modern REs. Die Syntax wird in den Man Pages re_format(7) und regex(7), die Teil von BSD- bzw. Linux-Systemen sind, ausführlich beschrieben. GNU grep(1) unterstützt auch Perl-kompatible REs, wie sie von der pcre(3)-Bibliothek bereitgestellt werden.
In der Regex-Sprache wird das Tabulator-Symbol in der Regel kodiert durch
\t
Atom. Das Atom wird von den erweiterten regulären Ausdrücken des BSD unterstützt (egrep
,grep -E
auf BSD-kompatiblen Systemen), sowie Perl-kompatible REs (pcregrep
, GNUgrep -P
).Sowohl die einfachen regulären Ausdrücke als auch die erweiterten REs von Linux haben offenbar keine Unterstützung für die
\t
. Bitte konsultieren Sie die Manpage des UNIX-Dienstprogramms, um zu erfahren, welche Regex-Sprache es unterstützt (daher der Unterschied zwischen sed(1), awk(1) und pcregrep(1) regulären Ausdrücken).Daher wird unter Linux:
$ grep -P '\t' FILE ...
Auf einem BSD-ähnlichen System:
$ egrep '\t' FILE ... $ grep -E '\t' FILE ...
-
Übergeben Sie das Tabulatorzeichen in das Muster. Dies ist ganz einfach, wenn Sie eine Skriptdatei bearbeiten:
# no tabs for Python please! grep -q ' ' *.py && exit 1
Wenn Sie jedoch in einer interaktiven Shell arbeiten, müssen Sie sich möglicherweise auf die Fähigkeiten der Shell und des Terminals verlassen, um das richtige Symbol in die Zeile einzugeben. Auf den meisten Terminals kann dies durch
Ctrl
+V
Tastenkombination, die das Terminal anweist, das nächste Eingabezeichen wörtlich zu behandeln (dieV
steht für "wortwörtlich"):$ grep '<Ctrl>+<V><TAB>' FILE ...
Einige Shells bieten erweiterte Unterstützung für den Befehlssatz. So werden in bash(1) Wörter der Form
$'string'
werden besonders behandelt:bash$ grep $'\t' FILE ...
Bitte beachten Sie jedoch, dass dies, auch wenn es in einer Befehlszeile schön ist, zu Kompatibilitätsproblemen führen kann, wenn das Skript auf eine andere Plattform übertragen wird. Seien Sie außerdem vorsichtig mit Anführungszeichen, wenn Sie die Specials verwenden, bitte konsultieren Sie bash(1) für Details.
Für die Bourne-Shell (und nicht nur für diese) kann das gleiche Verhalten mit Hilfe von Befehlssubstitutionen emuliert werden, die durch printf(1) ergänzt werden, um einen geeigneten Regex zu erstellen:
$ grep "`printf '\t'`" FILE ...
Eine gute Wahl ist die Verwendung von sed.
sed -n '/\t/p' file
Beispiele (funktioniert in bash, sh, ksh, csh,..):
[~]$ cat testfile
12 3
1 4 abc
xa c
a c\2
1 23
[~]$ sed -n '/\t/p' testfile
xa c
a c\2
[~]$ sed -n '/\ta\t/p' testfile
a c\2
(Diese Antwort wurde aufgrund von Anregungen in den Kommentaren überarbeitet. Vielen Dank an alle)