Bulk renamer shell script - Programming On Unix

Users browsing this thread: 1 Guest(s)
phillbush
Long time nixers
I have just written an interactive POSIX shell script for bulk renaming files.
I think it might be useful for more people.

When you call `bulkrename *`, it opens your favorite editor with the names of the files in the current directory for you to edit. Then, after closing the file, it renames the files to the names you edited.

`ls | bulkrename` also works.

Code:
#!/bin/sh
# bulkrename: bulk rename files using $EDITOR and temporary files
# this file in public domain

set -f -e -u

EDITOR="${EDITOR:-${VISUAL:-vi}}"

usage()
{
    echo "usage: bulkrename [file...]" >&2
    exit 1
}

# populate the files $old and $new with filenames, one per line
populatefiles()
{
    if [ $# -eq 0 ]
    then                            # run on stdin
        cat | tee "$old" > "$new"
    else                            # run on arguments
        for i
        do
            printf "%s\n" "$i" >> "$old"
            printf "%s\n" "$i" >> "$new"
        done
    fi
}

# edit the filenames in $new, test if they are valid, and rename the
# filenames in $old to the ones in $new
bulkrename()
{
    "$EDITOR" "$new" </dev/tty

    if cmp -s "$old" "$new"
    then
        echo "bulkrename: no change"
        exit 0
    fi

    if [ $(wc -l <"$new") -ne $(wc -l <"$old") ]
    then
        echo "bulkrename: number of filenames not equal to number of files"
        exit 1
    fi

    if [ "$(wc -l <"$new")" -ne "$(sort -u "$new" | wc -l)" ]
    then
        echo "bulkrename: repeated filenames to be renamed"
        exit 1
    fi

    # escape backslashes and insert 'mv ' before each line in $old
    sed -i "s/'/'\\\\''/g; s/^/mv '/; s/\$/'/" "$old"
    sed -i "s/'/'\\\\''/g; s/^/'/; s/\$/'/" "$new"

    # create file with the commands for renaming
    paste "$old" "$new" > "$cmd"

    sh -x "$cmd"
}

# remove temporary files
cleanup()
{
    rm -f "$old" "$new" "$cmd"
}

while getopts 'h' c
do
    case "$c" in
    h|*)
        usage
        ;;
    esac
done
shift $((OPTIND -1))

old=$(mktemp)
new=$(mktemp)
cmd=$(mktemp)

trap cleanup EXIT

populatefiles "$@"
bulkrename

exit 0

bulkrename(1) receives filenames from its arguments (one per argument) or from stdin (one per line) and opens an editor to edit them; then, it renames each file to the corresponding edited one.

If there are no arguments, bulkrename operates on stdin, reading one filename per line. If there are arguments, each argument is read as a filename.

The environment variables $EDITOR and $VISUAL are checked, in this order, for an editor program. If both are unset, use vi(1) by default.


Messages In This Thread
Bulk renamer shell script - by phillbush - 19-04-2020, 12:06 PM
RE: Bulk renamer shell script - by jkl - 20-04-2020, 08:04 AM
RE: Bulk renamer shell script - by phillbush - 20-04-2020, 09:26 AM
RE: Bulk renamer shell script - by z3bra - 20-04-2020, 10:21 AM
RE: Bulk renamer shell script - by phillbush - 20-04-2020, 10:28 AM
RE: Bulk renamer shell script - by z3bra - 20-04-2020, 03:45 PM
RE: Bulk renamer shell script - by jkl - 20-04-2020, 03:46 PM
RE: Bulk renamer shell script - by phillbush - 20-04-2020, 04:11 PM
RE: Bulk renamer shell script - by ckester - 20-04-2020, 05:49 PM