web-dev-qa-db-fra.com

Pourquoi la commande de canal "l | grep" 1 "" donne un résultat erroné?

Comme le montre l'image, j'utilise l pour obtenir le fichier dans le dossier actuel. Et puis je veux obtenir le fichier avec le numéro 1, alors j'utilise le pipe et le grep.

Mais pourquoi les fichiers 2 et 22 sont-ils affichés? Et quel est le 1;34m?

$ l
./ ../ 1 11 2 22
$ l | grep "1"
1;34m./ 1;32m../ 1 11 2 22

Mise à jour

J'ai déjà alias la commande l dans mon fichier zshrc.

 alias lsp="ls"
 alias ll='ls -alF'
 alias la='ls -A'
 alias l='ls -CF'
 alias ls="ls -alh --color"

Et voici le résultat de la commande type:

>$ type ls
ls is an alias for ls -alh --color

> $ type l
l is an alias for ls -CF
13
Lee

Tout d'abord, ce que vous essayez de faire, l| grep <filename> est mauvais. Ne le fais pas. Voici pourquoi.

La commande lest en réalité un alias de ls -CF

$ type -a l
l is aliased to `ls -CF'

Par défaut, dans bashde Ubuntu, lsest un alias de ls --color=auto. Comme Steeldriver l'a souligné dans les commentaires, --color=auto est censé désactiver la colorisation. Dans votre cas particulier, vous avez alias ls="ls -alh --color" et alias l="ls -CF", ce qui revient à ls -alh --color -CF. Cette combinaison particulière de commutateurs envoie toujours une sortie colorisée sur un tuyau. Par exemple:

$ ls -alh --color -CF ~/TESTDIR | cat -A                                                                                 
^[[0m^[[01;34m.^[[0m/  ^[[01;34m..^[[0m/  1.txt  2.txt  3.txt  out.txt$

Notez que les répertoires . et .. ont les mêmes séquences d'échappement.

Qu'est-ce-que tout cela veut dire

Cela signifie que lgénérera une liste colorisée de fichiers en fonction du type de fichier. Le problème est que la colorisation se produit avec l'utilisation de séquences d'échappement . C'est ce que sont les 1:34m - ce sont des séquences d'échappement pour des couleurs spécifiques.

Le principal problème est que l'analyse de lsconduit souvent à une sortie erronée et à des catastrophes dans les scripts, tout simplement parce que lspermet des séquences d'échappement telles que celles expliquées précédemment et d'autres caractères spéciaux. Voir cet article pour plus d'informations: http://mywiki.wooledge.org/ParsingLs

Ce que vous devriez faire:

Utilisez la commande findname__:

bash-4.3$ ls
1.txt  2.txt  3.txt  out.txt
bash-4.3$ find . -maxdepth 1 -iname "*1*"
./1.txt

Vous pouvez faire quelque chose comme ceci avec Shell glob et la commande moderne test [[:

bash-4.3$ for file in * ;do if [[ "$file" =~ "1"  ]] ;then echo "$file" ;fi ; done
1.txt

Ou peut-être utiliser python, qui a de bien meilleures capacités de gestion de nom de fichier que bashseul

bash-4.3$ python -c 'import os;print [f for f in os.listdir(".") if "1" in f ]'
['1.txt']

S'il n'est pas nécessaire de traiter la sortie de lsname__, une simple analyse par globulation avec lspeut également faire le travail. (Rappelez-vous, ceci est uniquement destiné à afficher la liste des fichiers, pas à le transmettre à un autre programme pour traiter le texte de sortie)

bash-4.3$ ls *1*
1.txt
27
Sergiy Kolodyazhnyy

Vos commandes l et ls sont configurées comme des alias.

Lorsque vous les exécutez, le résultat est transmis via grep "1" (en utilisant |), chaque ligne d'écran dans laquelle 1 apparaît, est affichée, avec le 1 de couleur rouge.

Étant donné que les noms de fichier ., .., 2 et 22 apparaissent sur la même ligne d'écran, ils sont également affichés par grep mais n'apparaissent pas en rouge, ce qui indique grep.

:34m est une séquence d'échappement pour une couleur qui ne peint pas correctement. Sur la base de votre question révisée avec la sortie de type -a l et type -a, elle peut être reproduite dans mon système. Veuillez noter que vous devez changer votre alias de --color à --color=auto:

Sortie couleur

color ls

6
WinEunuuchs2Unix

Dans votre version d'évaluation, vous appeliez votre alias ls, ainsi le 1;34m et le bruit similaire provenant de la coloration, et puisque le tube | reçoit tout cela sur la même ligne, le grep correspond au fichier 1 de cette ligne et imprime par conséquent cette ligne. C'est ce que vous voyez à l'écran.

Quand vous faites ce genre de choses, il est toujours bon de revenir à la commande système avec 1 résultat par ligne.

Pour vous débarrasser des alias, tapez simplement \ls et utilisez l'option -1 pour imprimer les résultats séparés par des sauts de ligne.

$ \ls -1 | grep "1"
1
11

Remarque: la méthode de barre oblique inverse fonctionne avec chaque commande, \command appelle simplement la commande système sans alias.

1
pilko