web-dev-qa-db-fra.com

Détection d'un motif à la fin d'une ligne avec grep

Si je fais:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

./Cloud:
UFAIZLV2R7.part2.rar.part
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part4.rar.part

Si je veux lister les .rar fichiers uniquement, et j'utilise grep , cela me montrera aussi le .rar.part fichiers, ce qui n'est pas mon souhait.
Je résous ce problème en utilisant find ou ls **/*.rar comme indiqué dans ce fil et ils fonctionnent très bien, mais j'aimerais savoir s'il est possible de le faire via grep.

J'ai essayé (en pensant à EOL):

ls -R | grep ".rar\n"

sans résultat.
Je pense que le problème consiste à découvrir si le greping est trouvé à la fin de la ligne , mais je ne suis pas sûr.

Vous avez de l'aide ici, s'il vous plaît?

72

Le $ l'ancre correspond à la fin d'une ligne.

ls -R | grep '\.rar$'

Vous pouvez également utiliser find pour cela:

find . -name '*.rar'
96
jordanm

En plus de votre question, veuillez noter que .rar ne correspond pas seulement à ".rar" mais correspond à chaque caractère (y compris .) avant le rar. Dans ce cas, ce n'est probablement pas un problème mais . doit être échappé dans les expressions rationnelles.

ls -R | grep "\.rar$"
11
Hauke Laging

Vous pouvez également demander à grep de rechercher votre chaîne en commençant par une limite de Word. UNE . est l'une de ces limites.

$ ls -R | grep '\brar$'

Exemple

Disons que j'ai ces exemples de données.

$ ls -1
afile.rar
xrar
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part2.rar.part

Cette commande ne trouverait que le fichier avec le .rar extension.

$ ls -R | grep '\brar$'
afile.rar

Comment ça marche?

Le métacaractère \b est une ancre comme le signe d'insertion et le signe dollar. Il correspond à une position appelée "limite de mot". Cette correspondance est de longueur nulle.

Situations où cela ne fonctionnera pas

Si vous avez des fichiers nommés blah-rar ceux-ci seront également détectés.

$ ls -R | grep '\brar$'
afile-rar
afile.rar

En effet, les caractères autres que les caractères alphanumériques sont généralement considérés comme des caractères de limite, et passeraient donc outre cette approche.

5
slm

Utilisez des guillemets simples pour que le $ fonctionne comme fin de ligne. Si vous souhaitez également utiliser grep avec une variable, utilisez une combinaison de guillemets doubles et simples comme ci-dessous:

grep "$var"'$'

Mon message précédent a été supprimé en disant qu'il était en double. Permettez-moi d'expliquer en quoi cela est différent.

Les autres articles mentionnent soit l'utilisation complète des guillemets doubles "", ou utilisation complète des guillemets simples ''. Ils ont tous deux leurs propres limites. Ce qui suit l'explique.

Le problème avec tous les guillemets doubles est le suivant: grep "pattern$" donne l'erreur suivante: Illegal variable name.

Et utiliser tous les guillemets simples fonctionne, mais si vous voulez une substitution de variable, tous les guillemets simples pas fonctionneront. Par exemple:

Si j'ai une chaîne A_BOOK, y compris d'autres chaînes dans un fichier FILE.

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

Si je mets le LIVRE sur une variable BK

set BK = BOOK

Si je grep avec tous les guillemets doubles, j'obtiens l'erreur suivante: grep "${BK}$" FILE*: 1er $ pour la substitution de variable, 2e pour la fin du motif ( Nom de variable non autorisé ).

Si je grep avec tous les guillemets simples, la substitution de variable ne se produit pas. grep '${BK}$' FILE ne renvoie rien

Si j'utilise une combinaison de guillemets doubles et simples, j'obtiens ce que j'attends. Des guillemets doubles pour la substitution de variables et des guillemets simples pour la fin du modèle.

$ grep "${BK}"'$'  # << gives expected output
A_BOOK
C_BOOK
1
user274900

Si après avoir suivi ce qui précède et que rien ne fonctionne, cela peut être dû à des fins de ligne. Pour corriger, faites: dos2unix pr0n.txt et refaites votre grep.

0
typelogic

Faites juste:

ls -1R -I"?" -I"??" -I"???" -I"*[!.][!r][!a][!r]"

Vous n'avez pas du tout besoin de grep.

REMARQUE: Ce qui précède fonctionne ... sauf qu'il obtient toujours au moins afile-rar et je ne comprends pas pourquoi. Je vais le laisser ici, mais je n'en suis pas fier. En tout cas, comme d'autres l'ont dit:

find . '*.rar'
0
mikeserv