Search code examples
regexbashsedbatch-rename

Bash script to Rename multiple files in subfolder to their folder name


I have the following file structure:

Applications/Snowflake/applications/Salford_100/wrongname_120.nui; wrongname_200_d.nui
Applications/Snowflake/applications/Salford_900/wrongname_120.nui; wrongname_200_d.nui
Applications/Snowflake/applications/Salford_122/wrongname_120.nui; wrongname_200_d.nui

And I want to rename the fles to the same name as the directories they're in, but the files with "_d" at the end should retain its last 2 characters. The file pattern would always be "salford_xxx" where xxx is always 3 digits. So the resulting files would be:

Applications/Snowflake/applications/Salford_100/Salford_100.nui; Salford_100_d.nui
Applications/Snowflake/applications/Salford_900/Salford_900.nui; Salford_900_d.nui
Applications/Snowflake/applications/Salford_122/Salford_122.nui; Salford_122_d.nui

The script would run from a different location in

Applications/Snowflake/Table-updater

I imagine this would require a for loop and a sed regex, but Im open to any suggestions. (Thanks @ghoti for your advice) I've Tried this, which currently does not account for files with "_d" yet and I just get one file renamed correctly. Some help would be appreciated.

cd /Applications/snowflake/table-updater/Testing/applications/salford_*

dcomp="$(basename "$(pwd)")"
for file in *; do
ext="${file##*.}"
mv -v "$file" "$dcomp.$ext"

done

Ive now updated the script following @varun advice (thank you) and it now also searches through all files in the parent dir that contain salford in the name, missing out the parent name. Please see below

#!/bin/sh
#
#  RenameToDirName2.sh
#
set -e

cd /Applications/snowflake/table-updater/Testing/Applications/

find salford* -maxdepth 1 -type d \( ! -name . \) -exec sh -c '(cd {}  &&
    (
        dcomp="$(basename "$(pwd)")"
        for file in *;
        do ext="${file#*.}"
            zz=$(echo $file|grep _d)
        if [ -z $zz ]
        then
            mv -v "$file" "$dcomp.$ext"
        else
            mv -v "$file" "${dcomp}_d.$ext"
    fi
done
)
)' ';'

The thing is, I've just realised that in these salford sub directories there are other files with different extensions that I don't want renaming. Ive tried putting in an else if statement to stipulate *.Nui files only, calling my $dcomp variable, like this

    else
    if file in $dcomp/*.nui
    then
     #continue...

But I get errors. Where should this go in my script and also do I have the correct syntax for this loop? Can you help?


Solution

  • @eggfoot,I have modified my script, which will look into all the directories in folder applications and look for for folders which have Salford in it. So you can call my script like this

    ./rename.sh /home/username/Applications/Snowflake e/applications

    #!/bin/bash
    #    set -x
    path=$1
    dir_list=$(find $path/ -type d)
    for index_dir in $dir_list
    do
        aa=$(echo $index_dir|grep Salford)
        if [ ! -z $aa ]
        then
                files_list=$(find $index_dir/ -type f)
                for index in $files_list
                do
                        xx=$(basename $index)
                        z=$(echo $xx|grep '_d')
                        if [ -z $z ]
                        then
                                result=$(echo $index | sed 's/\/\(.*\)\/\(.*\)\/\(.*\)\(\..*$\)/\/\1\/\2\/\2\4/')
                                mv "$index" "$result"
                        else
                                result=$(echo $index | sed 's/\/\(.*\)\/\(.*\)\/\(.*\)_d\(\..*$\)/\/\1\/\2\/\2_d\4/')
                                mv "$index" "$result"
                        fi
                done
        fi
      done
    

    Regarding sed, it uses the s command of sed and substitute the file name with directory name, keeping the extension as it is.

    Regarding your script, you need to use grep command to find files which have _d and than you can use parameter substitution changing the mv for files with _d and one without _d.

      dcomp="$(basename "$(pwd)")"
      for file in *; do
      ext="${file##*.}"
      zz=$(echo $file|grep _d)
      if [ -z $zz ]
      then
      mv -v "$file" "$dcomp.$ext"
      else
      mv -v "$file" "${dcomp}_d.$ext"
      fi
      done