web-dev-qa-db-fra.com

grep un onglet sous UNIX

Comment puis-je grep onglet (\ t) dans les fichiers de la plate-forme Unix?

387
Sachin Chourasiya

Si vous utilisez GNU grep, vous pouvez utiliser l'expression rationnelle de style Perl:

grep -P '\t' *
353
unwind

L'astuce consiste à utiliser le signe $ avant single guillemets. Cela fonctionne également pour couper et d'autres outils.

grep $'\t' sample.txt
293
antimirov

Je n'ai jamais réussi à faire fonctionner le métacaractère '\ t' avec grep. Cependant, j'ai trouvé deux solutions alternatives:

  1. Utiliser <Ctrl-V> <TAB> (appuyer sur Ctrl-V puis taper sur l'onglet)
  2. Utilisation de awk: foo | awk '/\t/'
82
SamK

De cette réponse sur Ask Ubuntu:

Dites à grep d'utiliser les expressions régulières définies par Perl (Perl a comme onglet \t):

grep -P "\t" <file name>

Utilisez le caractère de tabulation littéral:

grep "^V<tab>" <filename>

Utilisez printf pour imprimer un caractère de tabulation pour vous:

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

Une façon est (c'est avec Bash)

grep -P '\t'

-P active les expressions régulières Perl pour que\t fonctionne.

Comme l'utilisateur dérouler dit, cela peut être spécifique à GNU grep. L’alternative est d’insérer littéralement un onglet si le shell, l’éditeur ou le terminal le permet.

30
tjmoore

Une autre façon d'insérer l'onglet littéralement à l'intérieur de l'expression consiste à utiliser la citation $'\t' moins connue de Bash:

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

(Notez que si vous comparez des chaînes fixes, vous pouvez utiliser ceci avec le mode '-F'.)

Parfois, l’utilisation de variables peut rendre la notation un peu plus lisible et gérable:

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

Ce n'est pas exactement ce que vous recherchez, mais cela pourrait fonctionner dans votre cas.

grep '[[:blank:]]'

Équivalent à

grep -P '[ \t]'

Donc, il trouvera Space et Tab.

§ classes de caractères

Remarque, il n'est pas annoncé dans mon man grep, mais fonctionne toujours

 $ man grep | grep vierge | wc 
 0 0 0 
10
Steven Penny

Il existe fondamentalement deux façons de résoudre ce problème:

  1. (Recommended) Utilisez la syntaxe d'expression régulière prise en charge par grep (1). Modern grep (1) prend en charge deux formes de syntaxe regex POSIX 1003.2: de base (obsolètes) REs, et modernes REs. La syntaxe est décrite en détail dans les pages de manuel re_format (7) et regex (7) qui font respectivement partie des systèmes BSD et Linux. GNU grep (1) prend également en charge les RE compatibles Perl fournies par la bibliothèque pcre (3).

    En langage regex, le symbole de tabulation est généralement codé par \t atom. Le atom est pris en charge par les expressions régulières étendues BSD (egrep, grep -E sur un système compatible BSD), ainsi que par les RE compatibles Perl (pcregrep, GNU grep -P).

    Les expressions rationnelles de base et les RE étendues de Linux ne semblent apparemment pas prendre en charge le \t. Veuillez consulter la page de manuel des utilitaires UNIX pour connaître le langage regex pris en charge (d'où la différence entre les expressions régulières sed (1), awk (1) et pcregrep (1)).

    Par conséquent, sous Linux:

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

    Sur le même système BSD:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Passez le caractère de tabulation dans le motif. C'est simple quand vous éditez un fichier de script:

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

    Toutefois, lorsque vous travaillez dans un shell interactif, vous devrez peut-être faire appel à Shell et aux fonctionnalités de terminal pour taper le symbole approprié dans la ligne. Sur la plupart des terminaux, cette opération peut être effectuée à l'aide de la combinaison de touches Ctrl + V qui indique au terminal de traiter littéralement le prochain caractère saisi (le V correspond à "mot pour mot"):

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

    Certains shells peuvent offrir un support avancé pour la composition de commandes. En bash (1), tels mots de la forme $'string' sont spécialement traités:

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

    Veuillez noter cependant que bien que Nice soit en ligne de commande, cela peut générer des problèmes de compatibilité lorsque le script sera déplacé sur une autre plate-forme. Aussi, soyez prudent avec les citations lorsque vous utilisez les promos, veuillez consulter bash (1) pour plus de détails.

    Pour Bourne Shell (et pas seulement), le même comportement peut être émulé en utilisant une substitution de commande complétée par printf (1) pour construire une expression rationnelle appropriée:

    $ grep "`printf '\t'`" FILE ...
    
6
Mike Volokhov

Utilisez echo pour insérer la languette pour vous grep "$(echo -e \\t)"

6
vanjoe

grep "$(printf '\t')" a travaillé pour moi sur Mac OS X

4
kumar303

Un bon choix est d'utiliser 'sed as grep' (comme expliqué dans ce classique sed tutorial ).

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

Exemples (travaux en 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
2
Julio

utilisez gawk, définissez le délimiteur de champ sur tabulation (\ t) et vérifiez le nombre de champs. Si plus de 1, alors il y a/sont des onglets

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

+1, cela fonctionne en ksh, dash, etc: utilisez printf pour insérer TAB:

grep "$(printf 'BEGIN\tEND')" testfile.txt
1
Zsigmond Lőrinczy

Vous voudrez peut-être utiliser grep "$(echo -e '\t')"

La seule exigence est que echo soit capable d'interpréter les échappements de barre oblique inversée.

0
kshpolvind

Sur ksh j'ai utilisé

grep "[^I]" testfile
0
AIXroot

La réponse est plus simple. Écrivez votre grep et dans la citation tapez la touche de tabulation, cela fonctionne bien au moins en ksh

grep "  " *
0
YullyBear

La notation $ '\ t' donnée dans d'autres réponses est spécifique à Shell - elle semble fonctionner en bash et en zsh mais n'est pas universelle.

NOTE: Ce qui suit est pour le shell fish et ne fonctionne pas en bash:

Dans le shell fish, on peut utiliser un \t sans guillemets, par exemple:

grep \t foo.txt

Ou on peut utiliser les notations hex ou unicode, par exemple:

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

(ces notations sont utiles pour les caractères plus ésotériques)

Puisque ces valeurs doivent être sans guillemets, on peut combiner des valeurs entre guillemets et des guillemets par concaténation:

grep "foo"\t"bar"
0
Raman

Ces méthodes d'identification binaires alternatives sont totalement fonctionnelles. Et j'aime beaucoup l'utilisation de awk, car je ne pouvais pas me souvenir de l'utilisation syntaxique avec des caractères binaires simples. Cependant, il devrait également être possible d'attribuer une valeur à une variable Shell de manière portable POSIX (c'est-à-dire TAB = echo "@" | tr "\100" "\011"), puis de l'utiliser de partout, de manière portable POSIX; ainsi (par exemple, grep "$ TAB" nom de fichier). Bien que cette solution fonctionne bien avec TAB, elle fonctionnera également avec d'autres caractères binaires, lorsqu'une autre valeur binaire souhaitée est utilisée dans l'affectation (au lieu de la valeur du caractère de la tabulation to 'tr').

0
odoncaoa

Cela fonctionne bien pour AIX. Je recherche des lignes contenant JOINED<\t>ACTIVE

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

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

Utiliser la méthode 'sed-as-grep', mais remplacer les onglets par un caractère visible de préférence personnelle est ma méthode préférée, car elle indique clairement les fichiers contenant les informations demandées et leur emplacement dans les lignes:

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

Si vous souhaitez utiliser les informations de ligne/fichier, ou d’autres options de grep, mais souhaitez également voir le remplacement visible du caractère de tabulation, vous pouvez y parvenir en:

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

Par exemple:

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

EDIT: Évidemment, ce qui précède n’est utile que pour visualiser le contenu du fichier afin de localiser les onglets - si l’objectif est de gérer les onglets dans le cadre d’une session de script plus importante, cela ne sert à rien.

0
s8129