Come rinominare i file di backup, utilizzando la sua versione di backup come suffisso al nome del file e rendendolo non più nascosto

Aug 17 2020

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

1 Minty Aug 17 2020 at 09:57

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