web-dev-qa-db-fra.com

Comment faire pour grep pour les onglets sans utiliser les onglets littéraux et pourquoi cela ne fonctionne pas?

Lorsque je recherche des onglets dans un fichier avec (e) grep, j'utilise l'onglet littéral (^v + <tab>). Je ne peux pas utiliser \t en remplacement des onglets dans les expressions régulières. Avec par exemple sed cette expression fonctionne très bien.

Donc, y a-t-il une possibilité d'utiliser un remplacement non littéral pour <tab> et quels sont les arrière-plans pour un \t non fonctionnel/non interprété?

135
Lasall

grep utilise des expressions régulières définies par POSIX . Pour quelque raison que ce soit, POSIX n'a ​​pas défini \t en tant que tabulation.

Vous avez plusieurs alternatives:

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

    grep -P "\t" foo.txt
    

    la page de manuel indique qu'il s'agit d'une fonctionnalité "expérimentale". au moins \t semble fonctionner correctement. mais les fonctionnalités plus avancées de Perl regex pourraient ne pas l'être.

  • utilisez printf pour imprimer un caractère de tabulation pour vous:

    grep "$(printf '\t')" foo.txt
    
  • utilisez le caractère de tabulation littéral:

    grep "^V<tab>" foo.txt
    

    c’est-à-dire: tapez grep ", puis appuyez sur ctrl+v, puis sur tab, puis tapez " foo.txt. Si vous appuyez sur ctrl+v dans le terminal, la prochaine clé sera prise mot pour mot. cela signifie que le terminal insérera un caractère de tabulation au lieu de déclencher une fonction liée à la touche de tabulation.

  • utilisez la fonction citation de ansi de bash:

    grep $'\t' foo.txt
    

    cela ne fonctionne pas dans tous les coquillages.

  • utiliser awk:

    awk '/\t/'
    
  • utiliser sed:

    sed -n '/\t/p'
    

Voir le article de wikipedia sur les expressions régulières pour un aperçu des classes de caractères définies dans POSIX et d’autres systèmes.

190
lesmana

Ce n'est pas exactement la réponse que vous voudriez entendre, mais bash fournit une possibilité d'utilisation de séquences d'échappement.

command | grep $'\t'

(ne le mettez pas entre guillemets!).

12
enzotib

awk '/\t/' est ma solution préférée:

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

Sortie: a\t.

On peut toujours avoir recours à l’ascii hex-code pour onglet:

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

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

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