Wie tabuliere ich grep
(\ t) in Dateien auf der Unix-Plattform?
Wie tabuliere ich grep
(\ t) in Dateien auf der Unix-Plattform?
Antworten:
Wenn Sie GNU grep verwenden, können Sie den regulären Ausdruck im Perl-Stil verwenden:
grep -P '\t' *
-P
Option.
Der Trick besteht darin, vor einfachen Anführungszeichen das $ -Zeichen zu verwenden . Es funktioniert auch für Schnitt- und andere Werkzeuge.
grep $'\t' sample.txt
zsh
Soweit ich das beurteilen kann, funktioniert es auch. Könnten Sie die Semantik dieses $
Zeichens kommentieren ?
$'\t'' '
. Ein echtes Beispiel, das zeigt, dass es auch mit sh funktioniert (nicht nur Bash, das nicht standardmäßig auf Android installiert ist), ist busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems
.
Ich habe es nie geschafft, das Metazeichen '\ t' mit grep zum Laufen zu bringen. Ich habe jedoch zwei alternative Lösungen gefunden:
<Ctrl-V> <TAB>
(Strg-V drücken und dann Tabulator eingeben)foo | awk '/\t/'
| awk '/\t/'
Lösung funktioniert für alle Shells, Plattformen und Systeme.
awk
funktioniert hier gut, aber in einigen Tests auf meinem Computer mit sehr großen Dateien ist es ungefähr 30% langsamer als bei der Verwendung grep -P
. Dies kann je nach Anwendungsfall trivial und irrelevant sein und awk
ist einfach besser für die Lesbarkeit und Portabilität.
Aus dieser Antwort auf Ask Ubuntu:
Weisen Sie grep an, die von Perl definierten regulären Ausdrücke zu verwenden (Perl hat
\t
eine Registerkarte):grep -P "\t" <file name>
Verwenden Sie das wörtliche Tabulatorzeichen:
grep "^V<tab>" <filename>
Verwenden
printf
Sie diese Option , um ein Tabulatorzeichen für Sie zu drucken:grep "$(printf '\t')" <filename>
Ein Weg ist (dies ist mit Bash)
grep -P '\t'
-P
Aktiviert reguläre Perl-Ausdrücke, damit \ t funktioniert.
Wie User Unwind sagt, kann es spezifisch für GNU grep sein. Die Alternative besteht darin, dort buchstäblich eine Registerkarte einzufügen, wenn die Shell, der Editor oder das Terminal dies zulassen.
Eine andere Möglichkeit, die Registerkarte buchstäblich in den Ausdruck einzufügen, ist die Verwendung des weniger bekannten $'\t'
Zitats in Bash:
grep $'foo\tbar' # matches eg. 'foo<tab>bar'
(Beachten Sie, dass Sie diese Option mit dem Modus '-F' verwenden können, wenn Sie mit festen Zeichenfolgen übereinstimmen.)
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`
Dies ist nicht genau das, wonach Sie suchen, könnte aber in Ihrem Fall funktionieren
grep '[[:blank:]]'
Gleichwertig
grep -P '[ \t]'
So wird es Platz und Tab finden.
Beachten Sie, dass es in meinem nicht beworben wird man grep
, aber trotzdem funktioniert
$ man grep | grep blank | Toilette 0 0 0
-P
Argument wurde hinzugefügt.
Grundsätzlich gibt es zwei Möglichkeiten, dies zu beheben:
( Empfohlen ) Verwenden Sie die von grep (1) unterstützte Syntax für reguläre Ausdrücke. Modern grep (1) unterstützt zwei Formen der POSIX 1003.2-Regex-Syntax: grundlegende (veraltete) REs und moderne REs. Die Syntax wird ausführlich in den Manpages re_format (7) und regex (7) beschrieben, die Teil von BSD- bzw. Linux-Systemen sind. Das 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 normalerweise durch \t
Atom codiert . Das Atom durch BSD unterstützt reguläre Ausdrücke erweitert ( egrep
, grep -E
auf BSD kompatibles System) sowie Perl-kompatible REs ( pcregrep
GNU grep -P
).
Sowohl grundlegende reguläre Ausdrücke als auch erweiterte Linux-REs haben offenbar keine Unterstützung für das \t
. Bitte konsultieren Sie die UNIX-Dienstprogramm-Manpage, um zu erfahren, welche Regex-Sprache unterstützt wird (daher der Unterschied zwischen den regulären Ausdrücken sed (1), awk (1) und pcregrep (1)).
Daher unter Linux:
$ grep -P '\t' FILE ...
Auf BSD-ähnlichen Systemen:
$ egrep '\t' FILE ...
$ grep -E '\t' FILE ...
Übergeben Sie das Tabulatorzeichen in das Muster. Dies ist unkompliziert, 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 Shell- und Terminalfunktionen verlassen, um das richtige Symbol in die Zeile einzugeben. Bei den meisten Terminals kann dies durch eine Ctrl
+ V
Tastenkombination erfolgen, die das Terminal anweist, das nächste Eingabezeichen wörtlich zu behandeln (dies V
steht für "wörtlich"):
$ grep '<Ctrl>+<V><TAB>' FILE ...
Einige Shells bieten möglicherweise erweiterte Unterstützung für den Befehlssatz. Solche, in bash (1) Wörter der Form $'string'
werden speziell behandelt:
bash$ grep $'\t' FILE ...
Beachten Sie jedoch, dass dies zwar zu einer Befehlszeile führt, jedoch zu Kompatibilitätsproblemen führen kann, wenn das Skript auf eine andere Plattform verschoben wird. Seien Sie auch vorsichtig mit Zitaten, wenn Sie die Specials verwenden. Weitere Informationen finden Sie in Bash (1).
Für die Bourne-Shell (und nicht nur) kann dasselbe Verhalten mithilfe der durch printf (1) erweiterten Befehlssubstitution emuliert werden, um den richtigen regulären Ausdruck zu erstellen:
$ grep "`printf '\t'`" FILE ...
Verwenden Sie gawk, setzen Sie das Feldtrennzeichen auf tab (\ t) und überprüfen Sie die Anzahl der Felder. Wenn mehr als 1 vorhanden ist, gibt es Registerkarten
awk -F"\t" 'NF>1' file
awk /\t/
ist ausreichend für die Frage der Operation.
Eine gute Wahl ist die Verwendung von 'sed as grep' (wie in diesem klassischen sed-Tutorial erläutert ).
sed -n 's/pattern/&/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 's/\t/&/p' testfile
xa c
a c\2
[~]$ sed -n 's/\ta\t/&/p' testfile
a c\2
+1 Weg, der in ksh, dash usw funktioniert: benutze printf um TAB einzufügen:
grep "$(printf 'BEGIN\tEND')" testfile.txt
grep "$(printf '\t')" testfile.txt
Die Antwort ist einfacher. Schreiben Sie Ihren grep und geben Sie innerhalb des Anführungszeichens die Tabulatortaste ein, zumindest in ksh
grep " " *
Die Verwendung der 'sed-as-grep'-Methode, aber das Ersetzen der Registerkarten durch ein sichtbares Zeichen persönlicher Präferenz ist meine Lieblingsmethode, da sie deutlich zeigt, welche Dateien die angeforderten Informationen enthalten und wo sie in Zeilen platziert sind:
sed -n 's/\t/\*\*\*\*/g' file_name
Wenn Sie Zeilen- / Dateiinformationen oder andere Grep-Optionen verwenden möchten, aber auch den sichtbaren Ersatz für das Tabulatorzeichen sehen möchten, können Sie dies erreichen, indem Sie
grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'
Als Beispiel:
$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar
BEARBEITEN: Offensichtlich ist das Obige nur zum Anzeigen von Dateiinhalten zum Auffinden von Registerkarten nützlich. Wenn das Ziel darin besteht, Registerkarten als Teil einer größeren Skriptsitzung zu behandeln, hat dies keinen nützlichen Zweck.
Vielleicht möchten Sie verwenden grep "$(echo -e '\t')"
Die einzige Voraussetzung ist echo
, dass Backslash-Escapes interpretiert werden können.
Diese alternativen binären Identifikationsmethoden sind voll funktionsfähig. Und ich mag es wirklich, wenn jemand awk verwendet, da ich mich nicht genau an die syntaktische Verwendung mit einzelnen Binärzeichen erinnern konnte. Es sollte jedoch auch möglich sein, einer Shell-Variablen einen Wert in einer tragbaren POSIX-Weise (dh TAB = echo "@" | tr "\100" "\011"
) zuzuweisen und ihn dann von dort aus überall in einer tragbaren POSIX-Weise zu verwenden. auch (dh grep "$ TAB" Dateiname). Während diese Lösung gut mit TAB funktioniert, funktioniert sie auch gut mit anderen Binärzeichen, wenn ein anderer gewünschter Binärwert in der Zuweisung verwendet wird (anstelle des Werts für das TAB-Zeichen 'tr').
Die in anderen Antworten angegebene Notation $ '\ t' ist Shell-spezifisch - sie scheint in Bash und Zsh zu funktionieren, ist jedoch nicht universell.
HINWEIS: Folgendes gilt für die fish
Shell und funktioniert nicht in Bash :
In der fish
Shell kann man ein nicht zitiertes verwenden \t
, zum Beispiel:
grep \t foo.txt
Oder man kann die Hex- oder Unicode-Notationen verwenden, z.
grep \X09 foo.txt
grep \U0009 foo.txt
(Diese Notationen sind nützlich für esoterischere Zeichen.)
Da diese Werte nicht in Anführungszeichen gesetzt werden müssen, können zitierte und nicht in Anführungszeichen gesetzte Werte durch Verkettung kombiniert werden:
grep "foo"\t"bar"
Du kannst Tippen
grep \ t foo
grep '\ t' foo
um nach dem Tabulatorzeichen in der Datei foo zu suchen. Sie können wahrscheinlich auch andere Escape-Codes ausführen, obwohl ich nur \ n getestet habe. Obwohl es ziemlich zeitaufwändig und unklar ist, warum Sie es möchten, können Sie in zsh auch das Tabulatorzeichen eingeben, zurück zum Anfang, grep und den Tabulator in Anführungszeichen setzen.
Suchen Sie viele Male nach Leerzeichen [[: Leerzeichen:]] *
grep [[: space:]] * '.' '.'
Wird so etwas finden:
'die Registerkarte' ..
Dies sind einfache Anführungszeichen (') und keine doppelten (").
So machen Sie die Verkettung in grep. = -)
grep "<Ctrl+V><TAB>"
, es funktioniert (wenn das erste Mal: tippe,grep "
dann drücke Strg + V-Tastenkombination, dann drücke TAB-Taste, tippe"
und drücke die Eingabetaste, voilà!)