grep una scheda in UNIX


418

Come posso greptab (\ t) nei file sulla piattaforma Unix?


53
basta usare grep "<Ctrl+V><TAB>", funziona (se la prima volta: digita grep "quindi premi Ctrl + tasto V combinato, quindi premi il tasto TAB, quindi digita "e premi invio, voilà!)
torre

16
ctrl + v è un'IDEA VERAMENTE MALE! ... sì, potrebbe funzionare dal comando della console, ma potrebbe NON funzionare per digitarlo in uno script (sei in balia dell'editor, ad esempio io uso mcedit e ctrl + v NON funziona lì)
THESorcerer


Vedi anche: askubuntu.com/questions/53071/… (collegato anche di seguito)
shiri,

Risposte:


375

Se usi GNU grep, puoi usare il regexp in stile Perl:

grep -P '\t' *

Non sembra funzionare contro il mio modello. Il tentativo di utilizzare quella sintassi non stampa nulla. (La variante di Mac OS X è diversa?)
futureelite7,

2
@futureelite: secondo i documenti di Apple ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ), il programma grep di Mac OS X dovrebbe supportare l'opzione -P. Valuta la possibilità di creare una nuova domanda, su superuser.com.
Rilassati il

3
Questo è molto buono per GNU UNIX, ma per quanto riguarda POSIX Solaris, AIX e HP-UX? Quelli non sanno nulla -Pdell'opzione.
torre

21
@rook GNU non è UNIX.
Lily Chung,

5
in Mac OSX puoi dare uno schema usando -e
Faisal Feroz il

314

Il trucco è usare il segno $ prima delle virgolette singole . Funziona anche per il taglio e altri strumenti.

grep $'\t' sample.txt

7
La punta di Lifesavior salva la vita! Funziona zshpure, per quanto ne so. Potresti commentare qual è la semantica di quel $segno?
Romain,

2
Non funziona se la stringa contiene qualcosa di diverso da '\ t'. Come cercheresti "\ t" (tab + spazio) per esempio?
Raman,

6
Raman: puoi usare $'\t'' '. Un vero esempio che mostra che funziona anche con sh (non solo bash, che non è installato di default su Android) è busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak,

5
Penso che $ '...' sia un idioma bash. Probabilmente non funziona in sh. Non so di csh o tcsh.
Edward Falk,

5
Da 'man bash': le parole del modulo $ 'string' sono trattate in modo speciale. La parola si espande in stringa, con i caratteri con escape backslash sostituiti come specificato dallo standard ANSI C. Le sequenze di escape di barra rovesciata, se presenti, vengono decodificate ...
broeni,

84

Non sono mai riuscito a far funzionare il metacarattere "\ t" con grep. Tuttavia ho trovato due soluzioni alternative:

  1. Utilizzo <Ctrl-V> <TAB>(premendo Ctrl-V quindi digitando la scheda)
  2. Usando awk: foo | awk '/\t/'

4
La | awk '/\t/'soluzione funzionerà per tutte le shell, piattaforme e sistemi.
Samveen,

6
+1 per la soluzione POSIX portatile e non utilizzando basismi, zshismo, GNUismo e linuxismi.
Jens,

1
ctrl-V non è utile se si desidera copiare e incollare (dalle note o da uno script). Meglio usare una soluzione esplicita che ha un '\ t' visibile, i TAB letterali (cioè quelli che sembrano spazi bianchi) vengono spesso convertiti in SPC quando copypasting ...
plijnzaad

awk funziona bene qui ma in alcuni test sulla mia macchina con file molto grandi è circa il 30% più lento rispetto all'utilizzo grep -P . Questo potrebbe essere banale e irrilevante in base al caso d'uso e awkpotrebbe essere migliore semplicemente per leggibilità e portabilità.
theferrit32,

43

Da questa risposta su Chiedi a Ubuntu:

Di 'a grep di usare le espressioni regolari come definite da Perl (Perl ha \tcome tab):

grep -P "\t" <file name>

Usa il carattere di tabulazione letterale:

grep "^V<tab>" <filename>

Uso printf per stampare un carattere di tabulazione per te:

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


ctrl-V non è utile se si desidera copiare e incollare (dalle note o da uno script). Meglio usare una soluzione esplicita che abbia un '\ t' visibile, i TAB letterali (cioè quelli che sembrano spazi bianchi) vengono spesso convertiti in SPC durante il copypasting
plijnzaad

31

Un modo è (questo è con Bash)

grep -P '\t'

-P attiva le espressioni regolari Perl in modo che non funzionino.

Come utente rilassarsi dice, può essere specifico per GNU grep. L'alternativa è quella di inserire letteralmente una scheda se la shell, l'editor o il terminale lo consentono.


Opzione P sconosciuta nella shell ksh
Sachin Chourasiya,

Come dice svolgersi, può essere specifico per GNU grep. Appena chiarito.
tjmoore,

Come si aggiunge una scheda? Non avvia il processo di completamento automatico quando si preme il pulsante Tab? (che potrebbe funzionare in uno script bash ma non nella riga di comando)
AntonioCS

1
@AntonioCS come notato sopra da SamKrieg, per fare in modo che Shell ti consenta di digitare qualsiasi carattere, digita prima CTRL-v. Vedi anche askubuntu.com/questions/53071/…
Denis Arnaud il

2
-P è specifico per grep, non per nessuna shell. -P dovrebbe funzionare in qualsiasi shell, a condizione che GNU grep sia installato
plijnzaad

13

Un altro modo per inserire la scheda letteralmente all'interno dell'espressione è usare la $'\t'citazione meno conosciuta in Bash:

grep $'foo\tbar'        # matches eg. 'foo<tab>bar'

(Nota che se cerchi corrispondenze per stringhe fisse puoi usarlo con la modalità '-F'.)

A volte l'uso delle variabili può rendere la notazione un po 'più leggibile e gestibile:

tab=$'\t'               # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id"     # matches eg. `bob2<tab>323`

10

Questo non è esattamente quello che stai cercando, ma potrebbe funzionare nel tuo caso

grep '[[:blank:]]'

Equivalente a

grep -P '[ \t]'

Quindi troverà spazio e tabulazione.

§ Classi di caratteri

Nota, non è pubblicizzato nel mio man grep, ma funziona ancora

$ man grep | grep vuoto | bagno
      0 0 0

@ A-letubby Funziona ora con la modifica - l' -Pargomento è stato aggiunto.
villapx,

6

Usa l'eco per inserire la scheda per te grep "$(echo -e \\t)"


6

Esistono sostanzialmente due modi per affrontarlo:

  1. ( Consigliato ) Usa la sintassi delle espressioni regolari supportata da grep (1). Modern grep (1) supporta due forme di sintassi regex POSIX 1003.2: RE di base (obsolete) e moderne RE . La sintassi è descritta in dettaglio nelle pagine man re_format (7) e regex (7) che fanno parte rispettivamente dei sistemi BSD e Linux. GNU grep (1) supporta anche RE compatibili con Perl come fornito dalla libreria pcre (3).

    Nel linguaggio regex il simbolo della scheda è generalmente codificato \tdall'atomo. L'atomo è supportato da espressioni regolari estese BSD ( egrep, grep -Esu sistemi compatibili BSD), nonché da RE compatibili Perl ( pcregrep, GNU grep -P).

    Sia le espressioni regolari di base che le RE estese di Linux sembrano non avere supporto per \t . Consultare la pagina man dell'utilità UNIX per sapere quale linguaggio regex supporta (da qui la differenza tra espressioni regolari sed (1), awk (1) e pcregrep (1)).

    Pertanto, su Linux:

    $ grep -P '\t' FILE ...
    

    Su sistemi simili a BSD:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Passa il carattere di tabulazione nel modello. Questo è semplice quando si modifica un file di script:

    # no tabs for Python please!
    grep -q '   ' *.py && exit 1
    

    Tuttavia, quando si lavora in una shell interattiva, potrebbe essere necessario fare affidamento sulle funzionalità della shell e del terminale per digitare il simbolo corretto nella riga. Sulla maggior parte dei terminali questo può essere fatto attraverso la combinazione di tasti Ctrl+ Vche indica al terminale di trattare letteralmente il carattere di input successivo (il termine Vè "alla lettera"):

    $ grep '<Ctrl>+<V><TAB>' FILE ...
    

    Alcune shell possono offrire supporto avanzato per la composizione dei comandi. Tale, in bash (1) le parole del modulo $'string'sono trattate appositamente:

    bash$ grep $'\t' FILE ...
    

    Si noti tuttavia che, sebbene sia utile nella riga di comando, ciò può causare problemi di compatibilità quando lo script verrà spostato su un'altra piattaforma. Inoltre, fai attenzione con le virgolette quando usi le offerte speciali, consulta bash (1) per i dettagli.

    Per Bourne shell (e non solo) lo stesso comportamento può essere emulato usando la sostituzione di comando aumentata da printf (1) per costruire il regex corretto:

    $ grep "`printf '\t'`" FILE ...
    

4

grep "$(printf '\t')" ha funzionato per me su Mac OS X.


2

usa gawk, imposta il delimitatore di campo su tab (\ t) e controlla il numero di campi. Se più di 1, allora ci sono / sono le schede

awk -F"\t" 'NF>1' file

2
Questo è un po 'eccessivo e manca la domanda. awk /\t/è sufficiente per la domanda dell'op.
Espiazione limitata il

2

Una buona scelta è usare 'sed as grep' (come spiegato in questo classico tutorial di sed ).

sed -n 's/pattern/&/p' file

Esempi (funziona 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

Modo +1, che funziona in ksh, trattino, ecc: usa printf per inserire TAB:

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

Questo non ha funzionato per me su Ubuntu Trusty (Bash 4.3.11), tuttavia ha funzionato quanto segue:grep "$(printf '\t')" testfile.txt
Josh Rumbut,

0

La risposta è più semplice Scrivi il tuo grep e nella virgoletta digita il tasto tab, funziona bene almeno in ksh

grep "  " *

3
per prima cosa devi riuscire a inserire un carattere TAB nella tua shell - la maggior parte delle shell interpreta questa chiave come un comando (completamento)
Kaii


0

L'uso del metodo 'sed-as-grep', ma la sostituzione delle schede con un carattere visibile di preferenza personale è il mio metodo preferito, in quanto mostra chiaramente sia quali file contengono le informazioni richieste, sia anche dove sono posizionate all'interno delle linee:

sed -n 's/\t/\*\*\*\*/g' file_name

Se desideri utilizzare le informazioni sulla linea / sul file o altre opzioni grep, ma vuoi anche vedere il rimpiazzo visibile per il carattere della scheda, puoi farlo da

grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'

Come esempio:

$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar

EDIT: Ovviamente quanto sopra è utile solo per visualizzare i contenuti dei file per individuare le schede --- se l'obiettivo è gestire le schede come parte di una sessione di scripting più ampia, questo non ha alcuno scopo utile.


0

Questo funziona bene per AIX. Sto cercando righe contenentiJOINED<\t>ACTIVE

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

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

0

Potresti voler usare grep "$(echo -e '\t')"

L'unico requisito è echoessere in grado di interpretare le fughe di backslash.


0

Questi metodi di identificazione binaria alternativi sono totalmente funzionali. E, mi piace molto quello che usa awk, poiché non ricordo del tutto l'uso della sintassi con singoli caratteri binari. Tuttavia, dovrebbe anche essere possibile assegnare a una variabile shell un valore in modo portatile POSIX (cioè TAB = echo "@" | tr "\100" "\011"), e quindi impiegarlo da lì ovunque, in modo portatile POSIX; anche (es. grep "$ TAB" nomefile). Mentre questa soluzione funziona bene con TAB, funzionerà bene anche con altri caratteri binari, quando nell'assegnazione viene utilizzato un altro valore binario desiderato (anziché il valore per il carattere TAB su 'tr').


0

La notazione $ '\ t' fornita in altre risposte è specifica della shell - sembra funzionare in bash e zsh ma non è universale.

NOTA: quanto segue è per la fishshell e non funziona in bash :

Nella fishshell, si può usare un non quotato \t, ad esempio:

grep \t foo.txt

Oppure si possono usare le notazioni esadecimali o unicode, ad esempio:

grep \X09 foo.txt
grep \U0009 foo.txt

(queste notazioni sono utili per caratteri più esoterici)

Poiché questi valori devono essere non quotati, è possibile combinare i valori quotati e non quotati mediante concatenazione:

grep "foo"\t"bar"

-4

Puoi digitare

grep \ t foo

o

grep '\ t' pippo

per cercare il carattere di tabulazione nel file pippo. Probabilmente puoi anche fare altri codici di escape, anche se ho testato solo \ n. Sebbene sia piuttosto dispendioso in termini di tempo e non sia chiaro il motivo per cui vorresti, in zsh puoi anche digitare il carattere della scheda, tornare all'inizio, grep e racchiudere la scheda tra virgolette.


-6

Cerca spazi vuoti più volte [[: space:]] *

grep [[: space:]] * '.' '.'

Troverà qualcosa del genere:

'la scheda' ..

Queste sono virgolette singole (') e non doppie (").
Ecco come concatenare in grep. = -)

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.