Search code examples
fileunixgreprenamels

Rename all files found by extension in for loop


My task is to write a script that searches for all files without .old extension within given directory and renames files to this format: filename.old. I've tried this script:

#!/bin/bash
for i in $(grep "\.[^old]&" $1 | ls)
do
 mv "$1/$i" "$1/$i.old"
done

but it gives a wrong output.

  • These files were in my directory: f1, f2.old, f3, f4.old.
  • Expected output: f1.old, f2.old, f3.old, f4.old.
  • My output (1st launch): f1.old, f2.old.old, f3.old, f4.old.old. Each time when I launch script it keeps adding .old extension, so it becomes like this:
  • My output (2nd launch): f1.old.old, f2.old.old.old, f3.old.old, f4.old.old.old.

How can this be improved?


Solution

  • You could use a one-liner like so:

    find . -mindepth 1 ! -name '*.old' -exec mv {} {}.old \;
    

    Example on GNU/Linux (Ubuntu 14.04 LTS):

    mkdir so
    cd so
    touch f1 f2.old f3 f4.old
    find . -mindepth 1 ! -name '*.old' -exec mv {} {}.old \;
    ls
    

    Result:

    f1.old f2.old f3.old f4.old
    

    Explanation:

    You can modify your script like so to get similar result:

    test.sh.old

    #!/bin/bash
    for i in $(find . -mindepth 1 ! -name '*.old'); do
            mv "$i" "$i.old"
    done
    

    Execute with bash test.sh.old to get similar results.

    You may have to try some test cases to see if the one-liner and the modified test.sh.old file passes those test conditions. I tested it with the sample you provided and this returns the desired results.