J'ai un répertoire qui contient les fichiers suivants:
file1a file1ab file12A2 file1Ab file1ab
Je souhaite répertorier tous les fichiers commençant par file1
et suivi de deux lettres au plus!
La solution que j'ai proposée est la suivante:
ls | grep -i file1 [az] {2}
Mais ça ne marche pas!
Je veux savoir pourquoi? et comment lister?
Vous n'avez pas besoin de tuyauterie, grep
ou ls
. Il suffit d'utiliser Shell Globbing.
Dans bash
, en utilisant le modèle extglob
(doit être activé par défaut dans les sessions interactives, sinon faites shopt -s extglob
pour le définir en premier):
file1@(|?|??)
?
correspond à n'importe quel caractère, @(||)
sélectionne l'un des motifs séparés par |
.
Si vous vouliez uniquement faire correspondre des caractères compris entre a-z
et A-Z
, utilisez la classe de caractères [:alpha:]
, qui désigne tous les caractères alphabétiques des paramètres régionaux en cours:
file1@(|[[:alpha:]]|[[:alpha:]][[:alpha:]])
Exemple:
$ ls -1
file1
file112
file11a
file12A2
file1a
file1ab
file1Ab
file1as
file2
fileadb
$ ls -1 file1@(|[[:alpha:]]|[[:alpha:]][[:alpha:]]))
file1
file1a
file1ab
file1Ab
file1as
zsh
supporte cela nativement:
file1(|[[:alpha:]]|[[:alpha:]][[:alpha:]])
Je réponds à cette partie très à contrecoeur, à la demande de OP.
Tout futur lecteur, ne pas analyser ls
, utilisez globbing.
Utiliser ls
et grep
:
ls | grep -E '^file1[[:alpha:]]{,2}$'
Exemple:
% ls | grep -E '^file1[[:alpha:]]{,2}$'
file1
file1a
file1ab
file1Ab
file1as
Quoi de trouver?
find . -maxdepth 1 -regextype posix-egrep -iregex '\./file1[a-z]{,2}.*'
find
avec le drapeau -regex
est plus approprié pour ce type de travail, d’autant plus que c’est une règle générale que la sortie de ls ne doit jamais être analysée .
Cependant, vous avez indiqué que vous recherchiez des fichiers uniquement dans un répertoire (sans descendre dans les sous-répertoires), et que vous souhaitiez spécifiquement ls
et grep
. La solution est
\ls | grep -E 'file1[a-z]{2,}'
Considérant également que vous effectuez une recherche dans le répertoire en cours, mais en évitant d'analyser ls
, voici une autre solution.
for file in * ; do echo "$file" | grep -E 'file1[a-z]{2,}' ;done
./file1ab
./file1abc
Dans mon répertoire actuel, j'ai deux fichiers, file1ab
et file1abc
. Dans les deux cas, le résultat est le suivant:
xieerqi:$ for file in * ; do echo "$file" | grep -E 'file1[a-z]{2,}' ;done
./file1ab
./file1abc
xieerqi:$ \ls | grep -E 'file1[a-z]{2,}'
file1ab
file1abc