J'ai un dossier contenant environ 1 700 fichiers. Ils sont tous nommés comme 1.txt
ou 1497.txt
, etc. Je voudrais renommer tous les fichiers afin que tous les noms de fichiers comportent quatre chiffres.
C'est à dire., 23.txt
devient 0023.txt
.
Qu'est-ce qu'un script Shell qui fera cela? Ou une question connexe: comment utiliser grep pour ne faire correspondre que les lignes contenant \d.txt
(c'est-à-dire un chiffre, puis un point, puis les lettres txt
)?
Voici ce que j'ai jusqu'à présent:
for a in [command i need help with]
do
mv $a 000$a
done
Fondamentalement, exécutez cela trois fois, avec des commandes pour trouver un chiffre, deux chiffres et trois noms de fichiers (avec le nombre de zéros initiaux modifié).
Essayer:
for a in [0-9]*.txt; do
mv $a `printf %04d.%s ${a%.*} ${a##*.}`
done
Modifiez le modèle de nom de fichier ([0-9]*.txt
) le cas échéant.
Un renommage énuméré à usage général qui ne fait aucune hypothèse sur l'ensemble initial de noms de fichiers:
X=1;
for i in *.txt; do
mv $i $(printf %04d.%s ${X%.*} ${i##*.})
let X="$X+1"
done
Sur le même sujet:
En utilisant le script rename
(prename
dans certains cas) qui est parfois installé avec Perl, vous pouvez utiliser des expressions Perl pour effectuer le changement de nom. Le script ignore le changement de nom en cas de collision de noms.
La commande ci-dessous renomme uniquement les fichiers de quatre chiffres ou moins suivis d'une extension ".txt". Il ne renomme pas les fichiers qui ne sont pas strictement conformes à ce modèle. Il ne tronque pas les noms composés de plus de quatre chiffres.
rename 'unless (/0+[0-9]{4}.txt/) {s/^([0-9]{1,3}\.txt)$/000$1/g;s/0*([0-9]{4}\..*)/$1/}' *
Quelques exemples:
Original Becomes
1.txt 0001.txt
02.txt 0002.txt
123.txt 0123.txt
00000.txt 00000.txt
1.23.txt 1.23.txt
Les autres réponses données jusqu'à présent tenteront de renommer les fichiers qui ne sont pas conformes au modèle, produiront des erreurs pour les noms de fichiers qui contiennent des caractères non numériques, effectueront des renommages qui produisent des collisions de noms, essaieront et échoueront de renommer les fichiers qui ont des espaces dans leurs noms et éventuellement d'autres problèmes.
for a in *.txt; do
b=$(printf %04d.txt ${a%.txt})
if [ $a != $b ]; then
mv $a $b
fi
done
Bon mot:
ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", $0, $1) }' | xargs -n2 mv
Comment utiliser grep pour ne faire correspondre que les lignes contenant\d.txt (IE 1 chiffre, puis un point, puis les lettres txt)?
grep -E '^[0-9]\.txt$'
Supposons que vous ayez des fichiers avec le type de données .dat dans votre dossier. Copiez simplement ce code dans un fichier nommé run.sh, rendez-le exécutable en exécutant chmode +x run.sh
puis exécutez à l'aide de ./run.sh
:
#!/bin/bash
num=0
for i in *.dat
do
a=`printf "%05d" $num`
mv "$i" "filename_$a.dat"
let "num = $(($num + 1))"
done
Cela convertira tous les fichiers de votre dossier en filename_00000.dat
, filename_00001.dat
, etc.
Cette version prend également en charge la gestion des chaînes avant (après) le nombre. Mais fondamentalement, vous pouvez faire n'importe quel regex matching + printf tant que votre awk le prend en charge. Et il prend également en charge les espaces (sauf les retours à la ligne) dans les noms de fichiers.
for f in *.txt ;do
mv "$f" "$(
awk -v f="$f" '{
if ( match(f, /^([a-zA-Z_-]*)([0-9]+)(\..+)/, a)) {
printf("%s%04d%s", a[1], a[2], a[3])
} else {
print(f)
}
}' <<<''
)"
done
Pour ne faire correspondre que des fichiers texte à un chiffre, vous pouvez faire ...
$ ls | grep '[0-9]\.txt'
Indice d'une ligne:
while [ -f ./result/result`printf "%03d" $a`.txt ]; do a=$((a+1));done
RESULT=result/result`printf "%03d" $a`.txt
Pour fournir une solution qui est prudemment écrite pour être correcte même en présence de noms de fichiers avec des espaces:
#!/usr/bin/env bash
pattern='%04d' # pad with four digits: change this to taste
# enable extglob syntax: +([[:digit:]]) means "one or more digits"
# enable the nullglob flag: If no matches exist, a glob returns nothing (not itself).
shopt -s extglob nullglob
for f in [[:digit:]]*; do # iterate over filenames that start with digits
suffix=${f##+([[:digit:]])} # find the suffix (everything after the last digit)
number=${f%"$suffix"} # find the number (everything before the suffix)
printf -v new "$pattern" "$number" "$suffix" # pad the number, then append the suffix
if [[ $f != "$new" ]]; then # if the result differs from the old name
mv -- "$f" "$new" # ...then rename the file.
fi
done