Come rinominare i file di backup, utilizzando la sua versione di backup come suffisso al nome del file e rendendolo non più nascosto
Ho lavorato con un gran numero di file di immagine. Parte di questo è stato lo spostamento di tutti i tipi di file immagine distribuiti su più di 1000 directory in un'unica directory. C'erano molte immagini che avevano lo stesso nome esatto, ma in effetti erano immagini diverse. Ho usato il seguente one-liner per farlo:
find . -type f -exec mv --backup=t '{}' /media/DATA-HDD/AllImages \;
L'ho fatto in questo modo in modo che tutte le immagini con lo stesso nome avessero un file di backup nascosto, invece di sovrascriverle. Ha funzionato molto bene, ma ora ho un altro problema che devo risolvere.
Ora, ovviamente, ho molte tessere simili alle seguenti:
DSC_0616.NEF
DSC_0616.NEF.~1~
DSC_0616.NEF.~2~
Quello che sto cercando di fare è eseguire un comando (o uno script), che rinominerà uno qualsiasi di questi file nascosti aggiungendo il numero di backup come suffisso al nome del file e rimuoverà il. ~ [Bu #] ~ per renderli unici nomi di file e non nascosti. Quindi, in questo modo:
DSC_0616.NEF
DSC_0616_1.NEF
DSC_0616_2.NEF
Ho trascorso la maggior parte di un paio d'ore cercando di fare ricerche per tentare questo da solo, ma non riesco davvero a trovare nulla che possa aiutarmi ad arrivarci che rientra nel mio regno di conoscenza sull'argomento.
Risposte
Finché sei certo che tutto sia denominato in modo coerente come descritto sopra, alcune espressioni regolari possono svolgere il lavoro tramite uno script di shell:
#!/bin/bash
# sets the file separator to be only newlines, in case files have spaces in them
IFS=$'\n' for file in $(find . -type f); do
# parses just the number(s) between two tildes, and only at the end of the file
number=$(echo $file | grep -Eo "~[0-9]+~$" | sed s/'~'/''/g) # if no match found, assume this is a "base" file that does not need to be renamed if [ "$number" == "" ]; then
continue
fi
# parses the file name through "NEF", then deletes ".NEF"
filename=$(echo $file | grep -Eio "^.+\.NEF" | sed s/'\.NEF'/''/g )
if [ "$filename" == "" ]; then continue fi mv -v $file $(echo "$filename"_"$number.NEF") # if anything went wrong, exit immediately if [ "$?" != "0" ]; then
echo "Unable to move file $file"
exit 1
fi
done
Funzionerà anche per la discesa delle directory, basta posizionare lo script ed eseguirlo con la directory di lavoro all'inizio dell'albero delle directory del progetto. Funzionando con file di esempio come hai fornito:
###@###:~/project$ find . -type f
./DSC_0616.NEF.~8~
./DSC_0616.NEF.~5~
./DSC_0616.NEF.~1~
./DSC_0616.NEF.~7~
./DSC_0616.NEF.~3~
./DSC_0616.NEF.~4~
./DSC_0616.NEF.~9~
./DSC_0616.NEF.~2~
./DSC_0616.NEF.~6~
./lower_dir/DSC_0616.NEF.~8~
./lower_dir/DSC_0616.NEF.~5~
./lower_dir/DSC_0616.NEF.~1~
./lower_dir/DSC_0616.NEF.~7~
./lower_dir/DSC_0616.NEF.~3~
./lower_dir/DSC_0616.NEF.~4~
./lower_dir/DSC_0616.NEF.~9~
./lower_dir/DSC_0616.NEF.~2~
./lower_dir/DSC_0616.NEF.~6~
dopo aver eseguito lo script:
###@###:~/project$ find . -type f
./DSC_0616_1.NEF
./DSC_0616_3.NEF
./DSC_0616_7.NEF
./DSC_0616_5.NEF
./DSC_0616_2.NEF
./DSC_0616_9.NEF
./DSC_0616_6.NEF
./DSC_0616_8.NEF
./DSC_0616_4.NEF
./lower_dir/DSC_0616_1.NEF
./lower_dir/DSC_0616_3.NEF
./lower_dir/DSC_0616_7.NEF
./lower_dir/DSC_0616_5.NEF
./lower_dir/DSC_0616_2.NEF
./lower_dir/DSC_0616_9.NEF
./lower_dir/DSC_0616_6.NEF
./lower_dir/DSC_0616_8.NEF
./lower_dir/DSC_0616_4.NEF