Come richiedere le schede senza usare le schede letterali e perché non funziona?


146

Quando cerco schede in un file con (e) grep uso la scheda ( ^v + <tab>). Non posso utilizzare \tcome sostituto delle schede nelle espressioni regolari. Con ad esempio sed questa espressione funziona molto bene.

Quindi c'è qualche possibilità di usare un sostituto non letterale per <tab>e quali sono gli sfondi per un non funzionante / non interpretato \t?


Risposte:


206

grep utilizza espressioni regolari come definito da POSIX . Per qualsiasi motivo POSIX non è stato definito \tcome tab.

Hai diverse alternative:

  • dì a grep di usare le espressioni regolari come definite da perl (perl ha \tcome tab):

    grep -P "\t" foo.txt

    la pagina man avverte che questa è una funzione "sperimentale". almeno \tsembra funzionare bene. ma le funzionalità perge regex più avanzate potrebbero non esserlo.

  • usa printf per stampare un carattere tab per te:

    grep "$(printf '\t')" foo.txt
  • usa il carattere letterale tab:

    grep "^V<tab>" foo.txt

    vale a dire: digitare grep ", quindi premere ctrl+v, quindi premere tab, quindi digitare " foo.txt. la pressione ctrl+vnel terminale fa ritirare il tasto successivo alla lettera. ciò significa che il terminale inserirà un carattere di tabulazione invece di attivare una funzione associata al tasto tab.

  • usa la funzione di quotazione ansi c di bash:

    grep $'\t' foo.txt

    questo non funziona in tutte le shell.

  • usa awk:

    awk '/\t/'
  • usa sed:

    sed -n '/\t/p'

Vedi l' articolo di Wikipedia sulle espressioni regolari per una panoramica delle classi di caratteri definite in POSIX e altri sistemi.


basandomi sulla risposta di enzotib, vorrei aggiungere quanto segue: grep $'\t' foo.txt(ma di solito scrivo fgrepinvece di grep)
Walter Tross,

Ne avevo bisogno, combinato con l'utilizzo del valore di una variabile d'ambiente. Ho usato grep "$(printf '\t')${myvar}" foo.txt. Ha funzionato bene. Con pochi tentativi, non sono riuscito a far funzionare l'ultimo modulo.
sancho.s,

1
C'è qualche ragione che la pianura grepnon possa interpretare silenziosamente \tcome tab? POSIX richiede che \tsignifichi qualcos'altro? Forse dovrebbe corrispondere solo a un letterale \ seguito da un t?
Aaron McDaid l'

Forse vale la pena notare che BSD (incluso OSX) grep, manca l'opzione -P.
TextGeek

Dalla pagina man This is highly experimental and grep -P may warn of unimplemented features.Probabilmente non è una buona idea usare -Pnei sistemi legacy. La printfscelta è migliore
Avindra Goolcharan,

13

Non è esattamente la risposta che vorresti sentire, ma un possibile uso delle sequenze di escape è fornito da bash

command | grep $'\t'

(non metterlo tra virgolette!).


1
non è necessario per -E (ciò che viene cercato non è regex). Non è inoltre necessario eseguire il pipe da un comando. Detto questo, grazie per aver sottolineato questa caratteristica piuttosto trascurata di bash (stringhe a virgoletta singola precedute da $)
Walter Tross,

2
In effetti, suggerisco che @enzotib modifichi la risposta in modo semplice grep $'\t'.
Teemu Leisti,

Va sottolineato che questa è una caratteristica di bash e (silenziosamente!) Farà la cosa sbagliata se eseguita da qualche altra shell (come dash, che è l'impostazione predefinita per gli script di shell su Ubuntu e altri)
xjcl


1

Si può sempre ricorrere all'uso del codice esadecimale ASCII per tab:

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

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

$ grep $'\x9' input.txt                                            
one two
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.