Frage Wie grep für Tabs ohne Verwendung von literalen Tabs und warum nicht funktioniert?


Wenn ich mit (e) grep nach Tabs in einer Datei suche, benutze ich den Tab litteral (^v + <tab>). Ich kann es nicht nutzen \t als Ersatz für Registerkarten in regulären Ausdrücken. Mit z.B. sed dieser Ausdruck funktioniert sehr gut.

Gibt es also eine Möglichkeit, einen Ersatz ohne Ersatz zu verwenden? <tab> und was sind die Hintergründe für ein nicht arbeiten / nicht interpretiert \t ?


117
2017-07-14 11:59


Ursprung


stackoverflow.com/questions/1825552/grep-a-tab-in-unix - Ciro Santilli 新疆改造中心 六四事件 法轮功


Antworten:


grep verwendet reguläre Ausdrücke wie von definiert POSIX. Aus welchen Gründen auch immer, POSIX hat es nicht definiert \t als Registerkarte.

Sie haben mehrere Alternativen:

  • Weisen Sie Grep an, die regulären Ausdrücke zu verwenden, die von Perl definiert sind (perl hat \t als tab):

    grep -P "\t" foo.txt
    

    Die Manpage warnt, dass dies ein "experimentelles" Feature ist. mindestens \t scheint gut zu funktionieren. aber erweiterte Perl-Regex-Funktionen möglicherweise nicht.

  • Verwenden Sie printf, um ein Tab-Zeichen für Sie zu drucken:

    grep "$(printf '\t')" foo.txt
    
  • Verwenden Sie das Literal-Tab-Zeichen:

    grep "^V<tab>" foo.txt
    

    das ist: Typ grep ", dann drücken ctrl+v, dann drücken tab, dann tippe ein " foo.txt. Drücken ctrl+v im Terminal bewirkt, dass der nächste Schlüssel wörtlich genommen wird. Das bedeutet, dass das Terminal ein Tab-Zeichen einfügt, anstatt eine Funktion auszulösen, die an die Tab-Taste gebunden ist.

  • benutze die ansi c zitiert Merkmal der Bash:

    grep $'\t' foo.txt
    

    Dies funktioniert nicht in allen Shells.

  • benutze awk:

    awk '/\t/'
    
  • benutze sed:

    sed -n '/\t/p'
    

Siehe die Wikipedia-Artikel über reguläre Ausdrücke für einen Überblick über die definierten Zeichenklassen in POSIX und anderen Systemen.


164
2017-07-14 15:04



basierend auf enzotib's antwort lassen sie mich folgendes hinzufügen: grep $'\t' foo.txt (Aber ich würde normalerweise schreiben fgrep Anstatt von grep) - Walter Tross
Ich brauchte das, kombiniert mit dem Wert einer Umgebungsvariablen. ich benutzte grep "$(printf '\t')${myvar}" foo.txt. Es hat gut funktioniert. Mit ein paar Versuchen konnte ich das letzte Formular nicht zum Laufen bringen. - sancho.s
Gibt es einen Grund dafür? grep konnte nicht leise interpretieren \t als tab? Benötigt POSIX das? \t Bedeutst du etwas anderes? Vielleicht sollte es nur einem Literal entsprechen \  gefolgt von einem t? - Aaron McDaid
Vielleicht erwähnenswert, dass BSD (einschließlich OSX) Grep, fehlt die Option -P. - TextGeek
Von der Manpage This is highly experimental and grep -P may warn of unimplemented features. Wahrscheinlich keine gute Idee zu verwenden -P in Legacy-Systemen. Das printf die Wahl ist besser - Avindra Goolcharan


Es ist nicht genau die Antwort, die Sie hören möchten, aber eine mögliche Verwendung von Escape-Sequenzen wird von bash zur Verfügung gestellt

command | grep $'\t'

(nicht in Anführungszeichen setzen!).


12
2017-07-14 14:15



Es gibt keine Notwendigkeit für die -E (was gesucht wird, ist keine Regex). Es ist auch nicht erforderlich, von einem Befehl zu pipen. Das heißt, danke, dass Sie auf diese ziemlich übersehene Funktion von bash hingewiesen haben (Strings mit einfachen Anführungszeichen, denen $ vorausgeht). - Walter Tross
Tatsächlich schlage ich vor, dass @enzotib die Antwort einfach editiert grep $'\t'. - Teemu Leisti
Es sollte betont werden, dass dies eine Eigenschaft von bash ist und (still!) Das falsche tun wird, wenn es von einer anderen Shell ausgeführt wird (wie zum Beispiel das Bindestrich, das für Shell-Skripte unter Ubuntu und anderen Standard ist). - xjcl


awk '/\t/' ist meine bevorzugte Problemumgehung:

printf 'a\t\nb' | awk '/\t/'

Ausgabe: a\t.


2
2017-08-28 11:15





Man kann immer auf Ascii Hex-Code für Tab zurückgreifen:

$ echo "one"$'\t'"two" > input.txt                                 

$ grep -P "\x9" input.txt                                          
one two

$ grep $'\x9' input.txt                                            
one two

1
2017-07-03 17:04