Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
By ghostdog74 at 2008-09-13 21:50
Code:
#!/bin/bash
## Change file names into uppper/lower case, or by position.
NO_ARGS=0
E_OPTERROR=65
DEBUG=0
UPPER=0
FNAME="f"
maxdepth=1
directory=`pwd`
set -o noglob
#---- Functions ------------#
usage() {
printf "Usage: `basename $0` [-D directory] [-M depth] [-U ] [-p pattern] [-c position ][-d] [-X] [filename(s)]\n"
cat << EOF
-D : starting directory. Default=current directory
-M : max depth to recurse subdirectories (default=1), eg 1,2
-U : Change all letters to upper case. Default: change to all lower case
-c position : Change character at position to upper or lower (-U or -L)
-p pattern: Change the word matched by pattern to upper/lower case
-d : Debugging mode. Used to list all files to be changed, without changes taking effect
-X : Only check directory names, not file names
filename(s) : file names eg "*.txt". If omitted, default to all files. Use quotes.
Example:
1) -U -p file "*.txt" ===> change all name of text files with pattern "file" to upper case.
2) -U -c 10 "*.txt" ===> change the 10th character to upper case
3) -c 2 "*FILE*" ===> change the 2nd character to lower case for all files with pattern "FILE" in file name.
EOF
}
#----------------------------#
if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
then
usage
exit $E_OPTERROR # Exit and explain usage, if no argument(s) given.
fi
while getopts ":D:s:e:M:p:c:dUX" Option
do
case $Option in
D ) directory=$OPTARG
;;
d ) DEBUG=1 ;;
U ) UPPER=1;;
c ) position=$OPTARG
case ${position} in
0 | *[a-z]*) position=1;;
esac
;;
p ) pattern=$OPTARG
[ -z "${pattern}" ] && pattern=".*"
;;
M ) maxdepth=$OPTARG
case ${maxdepth} in
0 | *[a-z]*|"") maxdepth=1;;
esac
;;
X ) FNAME="d";;
* ) echo "Unimplemented option chosen."
exit;;
esac
done
shift $(($OPTIND - 1))
# get last argument
argument=$#
if [ $argument -eq 0 ];then
ext="*"
else
ext=$(eval echo \"\${${argument}}\")
fi
find "${directory}" -maxdepth "${maxdepth}" -type "${FNAME}" -name "$ext" -printf "%f:%h:%p\n" | \
awk -F":" -v pattern="${pattern}" -v debug="$DEBUG" -v upper=${UPPER} -v position="${position}" 'BEGIN{
q="\042"
}
$1 ~ pattern{
if ( upper ) {
if ( position>0 ) {
#change only positional characters to upper
newname = substr($1,1,position-1) toupper(substr($1,position,1)) substr($1,position+1)
}else if ( int(position)<0 ) {
#change to upper from the back
newname = substr($1,1,length($1)+position) toupper(substr($1,length($1)+position+1))
}else if ( !position ) {
# change all characters to upper
if ( pattern == ".*" ) {
newname = toupper($1)
}else {
newname=$1
gsub(pattern,toupper(pattern),newname)
}
}
}else if (!upper) {
if ( position>0 ) {
# change only positional characters to lower
newname = substr($1,1,position-1) tolower(substr($1,position,1)) substr($1,position+1)
}else if ( int(position)<0 ){
#change to lower from the back
newname = substr($1,1,length($1)+position) tolower(substr($1,length($1)+position+1))
}else if (!position) {
# change all characters to lower
if ( pattern == ".*" ) {
newname = tolower($1)
}else {
newname=$1
gsub(pattern,tolower(pattern),newname)
}
}
}
if ( newname == $1 ) {next}
if ( debug) {
print "mv -u " q $3 q " "q $2 "/" newname q
}else {
cmd = "mv -u " q $3 q " "q $2 "/" newname q
system(cmd)
}
}'
Usage:
The script makes use of GNU find/awk. Maximum depth value passed to "find" is set to default 1 level. Issue -M <level> to recurse more than 1 level of subdirectories. File types is set to search for files by default. Issue -X to search for directory names. If -D <directory> is omitted, the script searches from current working directory onwards.
Use -U ( or omit for lower case) for changing to upper case.
# Execute the script name without any arguments to show help.
> ./script.sh
# To see results before making actual changes, use the -d switch.
> ./script.sh -D /path/1 -U -p image -d "*.txt"
# To search text files in directories for 2 levels and change word "file" in their file names to Upper case
> ./script.sh -D /path/1 -M 2 -U -p "file" -d "*.txt"
# To search text files in current directory and change word "FILE" in their file names to lower case
> ./script.sh -p "FILE" "*.txt"
# To search text files in current directory and change the first character of each text file name to upper case
> ./script.sh -U -c 1 "*.txt"
# To search text files in current directory and change the last 2nd character onwards of each text file name to lower case
> ./script.sh -c -2 "*.txt"
# To rename all file names to capital letters
> ./script.sh -U -p ".*" "*.txt"
# To rename all file names to lower case letters
> ./script.sh -p ".*" "*.txt"
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.