Bulk renamer shell script - Programming On Unix

Users browsing this thread: 1 Guest(s)
phillbush
Long time nixers
(20-04-2020, 08:04 AM)jkl Wrote: Looks like your script does not support directories though:

Code:
+ mv TECOC TECOC
mv: cannot move 'TECOC' to a subdirectory of itself, 'TECOC/TECOC'

It does work with directories, but you tried to rename a directory to itself.
I will fix that, thanks for reporting the issue!

EDIT: Here is the new, fixed version. I just had to play with the read shell built-in and with file descriptors:

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
}

# quote and escape filename for moving
quote()
{
    echo "$1" | sed "s/'/'\\\\''/g; s/^/'/; s/\$/'/"
}

# 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 and test if they are valid
editfile()
{
    if [ "$(wc -l <"$old")" -ne "$(sort -u "$old" | wc -l)" ]
    then
        echo "bulkrename: repeated filenames to be renamed" >&2
        exit 1
    fi

    "$EDITOR" "$new" </dev/tty

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

    if [ "$(wc -l <"$new")" -ne "$(sort -u "$new" | wc -l)" ]
    then
        echo "bulkrename: repeated target filenames" >&2
        exit 1
    fi
}

# create $cmd file
createcmd()
{
    cat /dev/null >"$cmd"
    while read -r from <&3 && read -r to <&4
    do
        if [ "$from" != "$to" ]
        then
            from=$(quote "$from")
            to=$(quote "$to")
            printf "mv %s\t%s\n" "$from" "$to" >> "$cmd"
        fi
    done 3<"$old" 4<"$new"
}

# 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 "$@"
editfile
createcmd
sh -x "$cmd"

exit 0


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