UNIX :: Padding per i file contenenti string e multipleNumber
Ho molti file che non hanno nomi di file coerenti.
Per esempio
IMG_20200823_1.jpg
IMG_20200823_10.jpg
IMG_20200823_12.jpg
IMG_20200823_9.jpg
Vorrei rinominare tutti loro e assicurarmi che seguano tutti la stessa convenzione di denominazione
IMG_20200823_0001.jpg
IMG_20200823_0010.jpg
IMG_20200823_0012.jpg
IMG_20200823_0009.jpg
Ho scoperto che è possibile modificare per file che hanno solo un numero utilizzando di seguito
printf "%04d\n"
Tuttavia non sono in grado di fare con i miei file considerando che mescolano stringa + "_" + numeri diversi.
Qualcuno può aiutarmi ? Grazie !
Risposte
Con lo standalone renameo il prenamecomando di Perl :
rename -n 's/(\d+)(\.jpg$)/sprintf("%04d%s",$1,$2)/e' *.jpg
Produzione:
rinomina (IMG_20200823_10.jpg, IMG_20200823_0010.jpg) rinomina (IMG_20200823_12.jpg, IMG_20200823_0012.jpg) rinomina (IMG_20200823_1.jpg, IMG_20200823_0001.jpg) rinomina (IMG_20200823_9.jpg, IMG_20200823_0009.jpg)
se tutto sembra a posto, rimuovi -n.
Con le espressioni regolari di Bash:
re='(IMG_[[:digit:]]+)_([[:digit:]]+)'
for f in *.jpg; do
[[ $f =~ $re ]]
mv "$f" "$(printf '%s_%04d.jpg' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}")"
done
dove BASH_REMATCHè un array contenente i gruppi di cattura dell'espressione regolare. All'indice 0 è l'intera partita; l'indice 1 contiene IMG_e il primo gruppo di cifre; l'indice 2 contiene il secondo gruppo di cifre. Il printfcomando viene utilizzato per formattare il secondo gruppo con spaziatura zero, quattro cifre larghe.
Usa una regex per estrarre le sottostringhe pertinenti dall'input e poi riempila ...
- Per ogni file.
- Estrai il prefisso, il numero e il suffisso dal nome del file.
- Riempi il numero con zeri.
- Crea il nuovo nome file.
- Sposta i file
Il codice seguente per bash:
echo 'IMG_20200823_1.jpg
IMG_20200823_10.jpg
IMG_20200823_12.jpg
IMG_20200823_9.jpg' |
while IFS= read -r file; do # foreach file
# Use GNU sed to extract parts on separate lines
tmp=$(<<<"$file" sed 's/\(.*_\)\([0-9]*\)\(\..*\)/\1\n\2\n\3\n/')
# Read the separate parts separated by newlines
{
IFS= read -r prefix
IFS= read -r number
IFS= read -r suffix
} <<<"$tmp" # create new filename newfilename="$prefix$(printf "%04d" "$number")$suffix" # move the files echo mv "$file" "$newfilename"
done
uscite:
mv IMG_20200823_1.jpg IMG_20200823_0001.jpg
mv IMG_20200823_10.jpg IMG_20200823_0010.jpg
mv IMG_20200823_12.jpg IMG_20200823_0012.jpg
mv IMG_20200823_9.jpg IMG_20200823_0009.jpg
Restando perplesso dal tuo suggerimento a printf ...
Contenuto della cartella corrente:
$ ls -1 IMG_*
IMG_20200823_1.jpg
IMG_20200823_21.jpg
Sicuramente non è una buona soluzione ma con printf e sed possiamo farlo:
$ printf "mv %3s_%8s_%d.%3s %3s_%8s_%04d.%3s\n" $(ls -1 IMG_* IMG_* | sed 's/_/ /g; s/\./ /')
mv IMG_20200823_1.jpg IMG_20200823_0001.jpg
mv IMG_20200823_21.jpg IMG_20200823_0021.jpg