Comportement étrange de «ls -a | grep ^ \. ”


10

Je voulais lister le contenu d'un pwd et afficher uniquement le fichier commençant par un point. J'ai essayé ls -a | grep ^\.mais je ne peux pas comprendre pourquoi la sortie contient également les fichiers qui ne commencent pas par un point. Par exemple:

Pictures
.pip
.pki
.profile
projects
Public

Je sais que je peux réaliser ce que je veux avec ls -ld .*je suis juste curieux de ce comportement de grep que je ne peux pas expliquer.



Pourquoi ne pas simplement ls -d .*lister tous les fichiers commençant par .?
Barmar

Attention: ne dirigez jamais la sortie de ls vers une autre commande. Utilisez plutôt find. Il y a beaucoup trop d'idéosyncrasies pour faire confiance. Voir: Pitfall 1 sur mywiki.wooledge.org/BashPitfalls - il a fait # 1! Le reste du site est super aussi.
Joe

Réponses:


20

Citez l'argument pour grep, ainsils -a | grep '^\.'

La raison en est que le shell le gère \.et le transforme en clair ., qui est grepensuite traité comme un caractère générique à un seul caractère. En cas de doute, citez toujours une chaîne qui contient (ou peut contenir) un caractère spécial pour le shell.


Pourquoi le shell ignore-t-il \?
ps-aux

\ est une séquence d'échappement qui fait que le shell traite le caractère suivant comme un littéral. Dans ce cas grep ^\\., \\ est traité par le shell comme une simple barre oblique inverse et, à nouveau, le grep traite la barre oblique inverse unique suivie du point comme point littéral.
Avinash Raj

11

Vous devez mettre l'expression rationnelle grep entre guillemets.

ls -a | grep '^\.'

Remarque: N'analysez pas la sortie de la lscommande .


Pourquoi est-il mauvais d'analyser la sortie de ls?
ps-aux

Depuis le lien: Dans son mode par défaut, si la sortie standard n'est pas un terminal, ls sépare les noms de fichiers par des retours à la ligne. C'est très bien jusqu'à ce que vous ayez un fichier avec une nouvelle ligne dans son nom.
Michael Durrant

@Michael Durrant: Je dirais qu'autoriser les sauts de ligne dans les noms de fichiers est un bogue système majeur.
jamesqf

@jamesqf - voir les nouvelles lignes dans les noms de fichiers (en particulier la réponse de sml ).
don_crissti

0

Si vous exécutez cmd ls -a | grep ^ \. alors grep ne considère pas "\" comme un caractère spécial et une signification de "." ne vous échappez pas.

Lorsque nous utilisons cmd ls -a | grep "^ \." alors grep considère "\" comme un caractère spécial et une signification de "." s'échappe. Cela vous donnera un résultat comme prévu.

Si vous souhaitez utiliser grep cmd sans guillemets, vous devez également échapper le caractère "\". Vous pouvez avoir un résultat attendu sans guillemets doubles en suivant la commande. ls -a | grep ^ \\.

Pour plus de détails sur la signification des caractères spéciaux dans Regex, reportez-vous au lien suivant. http://www.regular-expressions.info/quickstart.html

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.