Skip to content

Instantly share code, notes, and snippets.

@jaydg
Last active March 5, 2018 23:01
Show Gist options
  • Save jaydg/fca5c728f44d5a38ab442b32008405e7 to your computer and use it in GitHub Desktop.
Save jaydg/fca5c728f44d5a38ab442b32008405e7 to your computer and use it in GitHub Desktop.
Rename multiple files at once (ksh88 and newer)
#!/bin/ksh
#
# Copyright (c) 2010,2011,2012 Joachim de Groot <jdegroot@web.de>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
usage() {
cat <<END
$0 [options] [operation] file...
operation is one of:
-a Append the given value to the file names
-c Chop the given value off the end of the file names
-n Number given files
-p Prepend the given value to the file names
-t Trim the given value off the beginning of the file names
Options:
-d dry run: show what would be done without touching anything
-f first number (numbering mode, default: 1)
-o offset between file numbers (numbering mode, default: 1)
-v verbose
-w file number width, zero padded (numbering mode, default: 1)
END
}
process() {
while (( $# > 0 )); do
FILE="$1"; shift
FN=${FILE##*/}
DN=${FILE%/*}
# Remember if the file to be renamed is in the current directory.
if [[ "$FN" != "$DN" ]]; then
NEED_PATH=1
else
NEED_PATH=0
fi
# generate new file name:
# process the desired changes
if [[ -n "$NUMBER" ]]; then
FN=$(printf "%0${WIDTH}d" $START)
START=$(( $START + $OFFSET ))
fi
if [[ -n "$TRIM" ]]; then
FN=${FN#"$TRIM"}
fi
if [[ -n "$CHOP" ]]; then
FN=${FN%"$CHOP"}
fi
if [[ -n "$PREPEND" ]]; then
FN="$PREPEND""$FN"
fi
if [[ -n "$APPEND" ]]; then
FN="$FN""$APPEND"
fi
# Assemble the file's new name
if [[ "$NEED_PATH" -eq 1 ]]; then
NEW_NAME="$DN"/"$FN"
else
NEW_NAME="$FN"
fi
rename "$FILE" "$NEW_NAME"
done
}
rename() {
OLD="$1"; shift;
NEW="$1"; shift;
if [[ "$OLD" = "$NEW" ]]; then
# no pattern matched, silently fail
return
fi
if [[ ! -f "$OLD" ]]; then
echo "$OLD: file not found."
return
fi
if [[ ! -w "$OLD" ]]; then
echo "$OLD: no write permission."
return
fi
if [[ -f "$NEW" ]]; then
echo "Cannot rename $OLD to $NEW: file exists."
return
fi
if [[ -n "$VERBOSE" || -n "$DRY_RUN" ]]; then
echo "'$OLD' -> '$NEW'"
fi
if [[ -z "$DRY_RUN" ]]; then
mv "$OLD" "$NEW"
fi
}
# Parameters for numbering files
typeset -i START=1
typeset -i OFFSET=1
typeset -i WIDTH=1
# Parse command line
while getopts "a:c:df:hno:p:t:vw:" OPTION; do
case $OPTION in
# OP: append param to the file name
a)
APPEND="$OPTARG"
;;
# OP: chop param from end of file name
c)
CHOP="$OPTARG"
;;
# OPTION: dry run
d)
DRY_RUN="y"
;;
# OPTION: First number
f)
START="$OPTARG"
;;
# OP: help
h)
usage
exit
;;
# OP: number files
n)
NUMBER="y"
;;
# OPTION: Numbering offset
o)
OFFSET="$OPTARG"
;;
# OP: prepend value to file name
p)
PREPEND="$OPTARG"
;;
# OP: trim param off the start of file name
t)
TRIM="$OPTARG"
;;
# OPTION: verbose
v)
VERBOSE="y"
;;
# OPTION: Number width
w)
WIDTH="$OPTARG"
;;
# Unknown switch
*)
usage
exit 1
;;
esac
done
# Removed parsed command line arguments
shift $(( $OPTIND - 1 ))
# Bail out if not supplied with file names
if (( $# == 0 )); then
usage
exit 1
fi
# Call function with remaining parameters
process "$@"
@jaydg
Copy link
Author

jaydg commented Feb 24, 2018

fr - rename multiple files

fr is a Korn shell script which allows to rename multiple files.
It is known to work with current ksh versions, but also with ksh88 on
Solaris 2.8 and OSF/1 4.0.

Available functions are:

  • add or remove a filename prefix
  • add or remove a filename suffix
  • number files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment