Comment puis-je grep
onglet (\ t) dans les fichiers de la plate-forme Unix?
Si vous utilisez GNU grep, vous pouvez utiliser l'expression rationnelle de style Perl:
grep -P '\t' *
L'astuce consiste à utiliser le signe $ avant single guillemets. Cela fonctionne également pour couper et d'autres outils.
grep $'\t' sample.txt
Je n'ai jamais réussi à faire fonctionner le métacaractère '\ t' avec grep. Cependant, j'ai trouvé deux solutions alternatives:
<Ctrl-V> <TAB>
(appuyer sur Ctrl-V puis taper sur l'onglet)foo | awk '/\t/'
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>
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.
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`
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.
Remarque, il n'est pas annoncé dans mon man grep
, mais fonctionne toujours
$ man grep | grep vierge | wc 0 0 0
Il existe fondamentalement deux façons de résoudre ce problème:
(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 ...
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 ...
Utilisez echo pour insérer la languette pour vous grep "$(echo -e \\t)"
grep "$(printf '\t')"
a travaillé pour moi sur Mac OS X
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
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
+1, cela fonctionne en ksh, dash, etc: utilisez printf pour insérer TAB:
grep "$(printf 'BEGIN\tEND')" testfile.txt
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.
Sur ksh j'ai utilisé
grep "[^I]" testfile
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 " " *
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"
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').
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
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.