Linux (or Unix) is a command line environment that is really powerful regarding file management. This power is no surprise as the basis of Unix and hence, Linux, is that files are at the heart of the design of the operating system … if you like, its kernel. Unix and Linux were designed for brevity, and so to read it does not always lead to immediate understanding, so, today, we present two scenarios you might want to do regarding the renaming of files in a shell script programmable way.
Before we start, let’s review seven things about the organization of the practicalities of shell script usage are:
- The first line is a good place to define which type of shell scripting you are working with … these lines start with “#!” and then define a “bin” directory for your shell type … ours goes #!/bin/sh
- The last line should contain “exit” if you want to go back to a parent command line environment on finishing
- Be consistent with file extension arrangements, or not … for ours, here, we have no extension … Unix and Linux are fine with this.
- The permissions of the resultant script should have relevant execute bits set … to go chmod 777 [yourScriptFile] … allows everyone to execute your script … the “1” in 1 + 21 + 22 = 7 relates to the execute bit of the file … the three 7’s relate to “Owner” then “Group” then “World”.
- Sometimes you would do this work in your current directory, set the permissions and just go [yourScriptFile] on the command line, but you may find you need to go ./[yourScriptFile] to make it happen.
- The power of scripting is the use of $1 $2 $3 etcetera referring to the parameters on the command line, allowing your single script to be “chameleon”-like in handling lots of scenarios … our examples today show bits of this type of parameter usage … but is the tip of the iceberg, as far as how your imagination should start working with what is possible!
- If you use parameters, there is, pretty obviously, lots of scope for bad “interactive” user usage … good to examine the user’s parameter usage, or not, and advise them about shell script advisory usage when they show signs of not knowing what is required by the script.
Here is the first renaming scenario … called “rname” … rename files from old extension to new extension in current directory …
#!/bin/sh
# rname
# Usage: Expecting parameters of old extension and then new extension used to rename files in current directory
if [ ! -z "$1" -a ! -z "$2" ]; then # were parameters $1 and $2 both defined?
e1=`echo $1 | sed '/[.]/s///g'` # rid any user usage confusion regarding . usage in extension ... sed is a "buffer pipe editor" (like tr)
e2=`echo $2 | sed '/[.]/s///g'`
for f in `ls *.$e1` # The ` ` is preprocessed and $f is looped through containing each filename satisfying the old extension criteria
do # Start of loop processing ...
if [ -f "`echo $f | sed '/[.]$e1/s//.$e2/g'`" ]; then # Start of if block asking if output file already existing ...
echo "Output `echo $f | sed '/[.]$e1/s//.$e2/g'` file already exists" # Warn user ... debatable "business logic" of script
else
mv $f `echo $f | sed '/[.]$e1/s//.$e2/g'` # Rename the file from old extension to new extension
fi # ... End of if block
done # ... End of loop processing
else
echo "Was expecting parameters of old extension and then new extension used to rename files in current directory" # Advise usage RE usage
fi
exit
Here is a link with fewer comments here you could rename to rname
Here is the second renaming scenario … called “mvfiles” … rename files from old extension to new nonexistant subdirectory to rename files in current directory …
#!/bin/sh
# mvfiles
# Usage: Expecting parameters of old extension and then new nonexistant subdirectory to rename files in current directory
if [ ! -z "$1" -a ! -z "$2" -a ! -d "$2" ]; then # were parameters $1 and $2 both defined, as well as parameter $2 not existing as a subdirectory (debatable)
e1=`echo $1 | sed '/[.]/s///g'` # rid any user usage confusion regarding . usage in extension ... sed is a "buffer pipe editor" (like tr)
mkdir $2 # create the non-existant parameter $2 subdirectory off the current directory
for f in `ls *.$e1` # The ` ` is preprocessed and $f is looped through containing each filename satisfying the old extension criteria
do # Start of loop processing ...
mv $f $2 # Rename the file from old extension to that newly created (previously) non-existant parameter $2 subdirectory
done # ... End of loop processing ...
else
echo "Was expecting parameters of old extension and then new nonexistant subdirectory to rename files in current directory" # Advise usage RE usage
fi
exit
Here is a link with fewer comments here you could rename to mvfiles
Today’s tutorial is based on a Yahoo Answers question here.
If this was interesting you may be interested in this too.