J'ai folderA
qui a quelques fichiers avec une séquence de numéros commençant par a_000000
. Ce que je veux faire, c'est supprimer des fichiers à partir d'un numéro spécifique: disons a_000750
jusqu'à la fin des fichiers folderA
. Quelqu'un pourrait-il s'il vous plaît indiquer comment faire cela en utilisant un script shell?
16
rm a_000[89]* a_0007[5-9]*
?a_000[89]*
inclut chaque fichier commençant para_0008
oua_0009
, eta_0007[5-9]*
inclut chaque fichier commençant para_0007
puis contenant un nombre compris entre 5 et 9, suivi de tout.Réponses:
En supposant que vous connaissez ou pouvez deviner la fin de la plage, vous pouvez utiliser des extensions d'accolade :
Ce qui précède supprimera les 101 fichiers entre a_000750 et a_000850 inclus (et se plaindra des noms de fichiers qui font référence à des fichiers inexistants). Si vous avez trop de fichiers pour cela, utilisez
find
:Ici, le
find
répertorie simplement tous les fichiers correspondantsa_*
. La liste est passée à unewhile
boucle où chaque nom de fichier est lu dans la variable$file
. Ensuite, en utilisant les fonctionnalités de manipulation de chaînes de bash , si la partie numérique (find imprime les fichiers en tant que./file
, donc${file#./a_}
imprime le nombre uniquement) est000750
ou plus, le fichier est supprimé. Le-v
est juste là pour que vous puissiez voir quels fichiers ont été supprimés.Notez que ce qui précède suppose des noms de fichier sensés. Si vos noms peuvent avoir des espaces, des retours à la ligne ou d'autres caractères étranges, utilisez-les à la place:
la source
[[
?[[
ne simplifie pas les choses ici[[ "${file#./a_}" > 000749 ]]
par exemple, ne les raccourcit même pas. Je n'aime pas utiliser une syntaxe inutile et celle-ci fonctionnera même dans des shells plus simples commedash
.[[
gère mieux les espaces et les bizarreries (je m'en fous beaucoup>
non plus).[
ça va si vous citez la variable comme moi, fonctionne sur beaucoup plus de shells et est plus simple.Vous pouvez faire quelque chose comme ça:
Ou:
La première méthode suppose un préfixe fixe, le supprime et vérifie la valeur.
La deuxième méthode suppose un suffixe de longueur fixe (et un préfixe fixe commun) et s'appuie sur ce fait; et que, tout en
201
qu'avant31
en lexicographiquement, il ne le fait pas avant031
.Testez-le avec la
echo
commande, et une fois que vous êtes sûr qu'il répertorie les fichiers corrects, utilisezrm
plutôt.la source
Solution shell POSIX
La première solution de terdon repose sur l'expansion des accolades, qui est une propriété de
bash
etksh
, cependant, elle ne peut pas être utilisée dans le/bin/sh
shell standard , qui sur Ubuntu est lié à/bin/dash
.Dans les cas où vous devez vous fier
/bin/sh
à la portabilité de vos scripts, il y a généralement deux façons d'aborder cela. On serait via globbing. Justecd folderA
et à partir de là, courezrm a_*
. L'autre façon, serait d'implémenter une alternative de style C pour les boucles en utilisantwhile <CONDITION>;do ...done
en langage shell et de formater les nombres avecprintf
:Notez qu'ici j'utilise
echo
. Remplacezecho "$filename"
parrm ./"$filename"
ourm -- "$filename"
lorsque vous êtes prêt à supprimer les fichiers. Notez également que cela doit être effectué lorsque vous avez déjàcd
édité dans le répertoire souhaité.(ab) en utilisant awk
Awk étant un joli langage de type C peut nous aider de deux manières: (1) nous pouvons générer des noms de fichiers avec for-loop et les formater via une
sprintf
fonction, et (2) supprimer lesdits fichiers via unesystem()
commande, qui passera notre nom de fichier généré et larm
commande à/bin/sh
:Perl
Poursuivant avec l'idée d'une approche portable où nous "générons" des noms de fichiers, nous pouvons faire de même en Perl:
la source
Aussi simple que
Dans votre exemple, c'est
la source
a_00075
...