grep eine Registerkarte in UNIX


417

Wie tabuliere ich grep(\ t) in Dateien auf der Unix-Plattform?


53
einfach benutzen 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à!)
Turm

16
Strg + V ist eine wirklich schlechte Idee! ... ja, es funktioniert möglicherweise über den Konsolenbefehl, aber es funktioniert möglicherweise nicht, um es in einem Skript einzugeben (Sie sind dem Editor ausgeliefert, zum Beispiel verwende ich mcedit und Strg + v funktioniert dort NICHT)
THESorcerer


Siehe auch: askubuntu.com/questions/53071/… (auch unten verlinkt)
shiri

Antworten:


374

Wenn Sie GNU grep verwenden, können Sie den regulären Ausdruck im Perl-Stil verwenden:

grep -P '\t' *

Es scheint nicht gegen mein Muster zu funktionieren. Der Versuch, diese Syntax zu verwenden, gibt nichts aus. (Ist die Mac OS X-Variante anders?)
futureelite7

2
@futureelite: Laut Apples Dokumenten ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ) sollte das Mac OS X grep-Programm die Option -P unterstützen. Erwägen Sie, eine neue Frage auf superuser.com zu erstellen.
Entspannen Sie

3
Das ist sehr gut für GNU UNIX, aber was ist mit POSIX Solaris, AIX und HP-UX? Die wissen nichts über -POption.
Turm

21
@rook GNU ist nicht UNIX.
Lily Chung

5
In Mac OSX können Sie Muster mit -e
Faisal Feroz

314

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

7
Lebensrettungstipp rettet Leben! zshSoweit ich das beurteilen kann, funktioniert es auch. Könnten Sie die Semantik dieses $Zeichens kommentieren ?
Romain

2
Funktioniert nicht, wenn der String etwas anderes als '\ t' enthält. Wie würden Sie zum Beispiel nach "\ t" (Tab + Leerzeichen) suchen?
Raman

6
Raman: Du kannst benutzen $'\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.
v6ak

5
Ich denke, $ '...' ist eine Bash-Sprache. Funktioniert wahrscheinlich nicht in sh. Keine Ahnung von csh oder tcsh.
Edward Falk

5
Aus 'man bash': Wörter der Form $ 'string' werden speziell behandelt. Das Wort wird zu Zeichenfolge erweitert, wobei Zeichen mit Backslash-Escapezeichen gemäß ANSI C-Standard ersetzt werden. Backslash-Escape-Sequenzen, falls vorhanden, werden dekodiert ...
broeni

84

Ich habe es nie geschafft, das Metazeichen '\ t' mit grep zum Laufen zu bringen. Ich habe jedoch zwei alternative Lösungen gefunden:

  1. Verwenden von <Ctrl-V> <TAB>(Strg-V drücken und dann Tabulator eingeben)
  2. Mit awk: foo | awk '/\t/'

4
Die | awk '/\t/'Lösung funktioniert für alle Shells, Plattformen und Systeme.
Samveen

6
+1 für die tragbare POSIX-Lösung und ohne Verwendung von Bashismen, Zshism, GNUism und Linuxismen.
Jens

1
Strg-V ist nicht nützlich, wenn Sie kopieren und einfügen möchten (aus Ihren Notizen oder einem Skript). Verwenden Sie besser eine explizite Lösung mit einem sichtbaren '\ t'. Literale TABs (dh solche, die wie Leerzeichen aussehen) werden beim Copypasting häufig in SPC konvertiert ...
plijnzaad

awkfunktioniert 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 awkist einfach besser für die Lesbarkeit und Portabilität.
Theferrit32

43

Aus dieser Antwort auf Ask Ubuntu:

Weisen Sie grep an, die von Perl definierten regulären Ausdrücke zu verwenden (Perl hat \teine Registerkarte):

grep -P "\t" <file name>

Verwenden Sie das wörtliche Tabulatorzeichen:

grep "^V<tab>" <filename>

Verwenden printfSie diese Option , um ein Tabulatorzeichen für Sie zu drucken:

grep "$(printf '\t')" <filename>


Strg-V ist nicht nützlich, wenn Sie kopieren und einfügen möchten (aus Ihren Notizen oder einem Skript). Verwenden Sie besser eine explizite Lösung mit einem sichtbaren '\ t'. Literale TABs (dh solche, die wie Leerzeichen aussehen) werden beim Copypasting häufig in SPC konvertiert
plijnzaad

31

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.


Unbekannte P-Option in ksh Shell
Sachin Chourasiya

Wie Unwind sagt, kann spezifisch für GNU grep sein. Nur geklärt.
tjmoore

Wie fügt man eine Registerkarte hinzu? Startet es nicht den automatischen Vervollständigungsprozess, wenn Sie die Tabulatortaste drücken? (Das könnte in einem Bash-Skript funktionieren, aber nicht in der Befehlszeile)
AntonioCS

1
@AntonioCS wie oben von SamKrieg erwähnt. Damit die Shell ein beliebiges Zeichen eingeben kann, geben Sie zuerst STRG-v ein. Siehe auch askubuntu.com/questions/53071/…
Denis Arnaud

2
-P ist spezifisch für grep, nicht für irgendeine Shell. -P sollte in jeder Shell funktionieren, vorausgesetzt, GNU grep ist installiert
plijnzaad

13

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`

10

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.

§ Zeichenklassen

Beachten Sie, dass es in meinem nicht beworben wird man grep, aber trotzdem funktioniert

$ man grep | grep blank | Toilette
      0 0 0

@ A-letubby Es funktioniert jetzt mit der Bearbeitung - das -PArgument wurde hinzugefügt.
Villapx

6

Verwenden Sie echo, um die Registerkarte für Sie einzufügen grep "$(echo -e \\t)"


6

Grundsätzlich gibt es zwei Möglichkeiten, dies zu beheben:

  1. ( 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 \tAtom codiert . Das Atom durch BSD unterstützt reguläre Ausdrücke erweitert ( egrep, grep -Eauf BSD kompatibles System) sowie Perl-kompatible REs ( pcregrepGNU 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 ...
    
  2. Ü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+ VTastenkombination erfolgen, die das Terminal anweist, das nächste Eingabezeichen wörtlich zu behandeln (dies Vsteht 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 ...
    

4

grep "$(printf '\t')" arbeitete für mich unter Mac OS X.


2

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

2
Dies ist ein bisschen übertrieben und übersieht die Frage. awk /\t/ist ausreichend für die Frage der Operation.
Begrenzte Versöhnung

2

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

+1 Weg, der in ksh, dash usw funktioniert: benutze printf um TAB einzufügen:

grep "$(printf 'BEGIN\tEND')" testfile.txt

Dies funktionierte nicht für mich unter Ubuntu Trusty (Bash 4.3.11), aber Folgendes funktionierte:grep "$(printf '\t')" testfile.txt
Josh Rumbut

0

Die Antwort ist einfacher. Schreiben Sie Ihren grep und geben Sie innerhalb des Anführungszeichens die Tabulatortaste ein, zumindest in ksh

grep "  " *

3
Zuerst müssen Sie es schaffen, ein TAB-Zeichen in Ihre Shell einzugeben - die meisten Shells interpretieren diesen Schlüssel als Befehl (Abschluss)
Kaii


0

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.


0

Dies funktioniert gut für AIX. Ich suche nach Zeilen mitJOINED<\t>ACTIVE

voradmin cluster status | grep  JOINED$'\t'ACTIVE

 vorudb201   1       MEMBER(g) JOINED        ACTIVE
*vorucaf01   2       SECONDARY JOINED        ACTIVE

0

Vielleicht möchten Sie verwenden grep "$(echo -e '\t')"

Die einzige Voraussetzung ist echo, dass Backslash-Escapes interpretiert werden können.


0

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').


0

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 fishShell und funktioniert nicht in Bash :

In der fishShell 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"

-4

Du kannst Tippen

grep \ t foo

oder

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.


-6

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. = -)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.