Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Renaming and Moving Files in Bash or Perl

HI, I'm completely new to Bash and StackOverflow.

I need to move a set of files (all contained in the same folder) to a target folder where files with the same name could already exist.

In case a specific file exists, I need to rename the file before moving it, by appending for example an incremental integer to the file name.

The extensions should be preserved (in other words, that appended incremental integer should go before the extension). The file names could contain dots in the middle.

Originally, I was thinking about comparing the two folders to have a list of the existing files (I did this with "comm"), but then I got a bit stuck. I think I'm just trying to do things in the most complicated possible way.

Any hint to do this in the "bash way"? It's OK if it is done in a script other than bash script.

like image 467
Katie Avatar asked Mar 30 '10 21:03

Katie


2 Answers

If you don't mind renaming the files that already exist, GNU mv has the --backup option:

mv --backup=numbered * /some/other/dir
like image 80
Ignacio Vazquez-Abrams Avatar answered Nov 02 '22 12:11

Ignacio Vazquez-Abrams


Here is a Bash script:

source="/some/dir"
dest="/another/dir"
find "$source" -maxdepth 1 -type f -printf "%f\n" | while read -r file
do
    suffix=
    if [[ -a "$dest/$file" ]]
    then
        suffix=".new"
    fi
    # to make active, comment out the next line and uncomment the line below it
    echo 'mv' "\"$source/$file\"" "\"$dest/$file$suffix\""
    # mv "source/$file" "$dest/$file$suffix"
 done

The suffix is added blindly. If you have files named like "foo.new" in both directories then the result will be one file named "foo.new" and the second named "foo.new.new" which might look silly, but is correct in that it doesn't overwrite the file. However, if the destination already contains "foo.new.new" (and "foo.new" is in both source and destination), then "foo.new.new" will be overwritten).

You can change the if above to a loop in order to deal with that situation. This version also preserves extensions:

source="/some/dir"
dest="/another/dir"
find "$source" -maxdepth 1 -type f -printf "%f\n" | while read -r file
do
    suffix=
    count=
    ext=
    base="${file%.*}"
    if [[ $file =~ \. ]]
    then
        ext=".${file##*.}"
    fi
    while [[ -a "$dest/$base$suffix$count$ext" ]]
    do
        (( count+=1 ))
        suffix="."
    done
    # to make active, comment out the next line and uncomment the line below it
    echo 'mv' "\"$source/$file\"" "\"$dest/$file$suffix$count$ext\""
    # mv "$source/$file" "$dest/$file$suffix$count$ext"
done
like image 34
Dennis Williamson Avatar answered Nov 02 '22 13:11

Dennis Williamson