Files
q-tools/files/mvregex
2016-05-23 14:00:09 +03:00

135 lines
4.7 KiB
Bash
Executable File

#!/bin/bash
function helpexit() {
echo 'Rename files in current folder, replacing with regex: arg1 -> arg2.'
echo 'Example: "_\([0-9]\)" "_X\1"'
echo 'Options:'
echo ' --ng Do _not_ replace globally (applies to regex replace only)'
echo ' --nc Do _not_ color output'
echo 'Modes:'
echo ' -n to match non-ascii and non-printable characters, and replace to [arg1]'
echo ' -f to replace match [arg1] with format [arg2], ex: -f "[0-9]\+" "%04d"'
exit
}
[[ -z "$1" ]] && helpexit
HIGHLIGHTSRC='\x1b[1;33;40m'
HIGHLIGHTTGT='\x1b[1;32;40m'
RESET='\x1b[0m'
GLOBAL="g"
unset TGT
MODE=regex
for (( i=1; i<=$#; i++ ))
do [[ "${!i}" = "-h" ]] && helpexit
[[ "${!i}" = "--nc" ]] && {
RESET=""
HIGHLIGHTSRC=""
HIGHLIGHTTGT=""
continue
}
[[ "${!i}" = "--ng" ]] && {
GLOBAL=""
continue
}
[[ "${!i}" = "-n" ]] && {
MODE=nonascii
continue
}
[[ "${!i}" = "-f" ]] && {
MODE=printf
continue
}
[[ -z "$SRC" ]] && {
SRC="${!i}"
continue
}
TGT="${!i}"
done
IFS=$'\n'
LS="ls"
$LS --version | grep -q GNU && LS="ls -v"
LONGEST=8
c=0
if [ "$MODE" = "nonascii" ]; then
## Remove non-ascii characters
for file in $( eval $LS | grep -P "[\x00-\x1F]" ); do [[ ${#file} -gt ${LONGEST} ]] && LONGEST=${#file}; done
for file in $( eval $LS | grep -P "[\x80-\xFF]" ); do [[ ${#file} -gt ${LONGEST} ]] && LONGEST=${#file}; done
printf "%-${LONGEST}s\t|%s\n" Matching Replaced
for file in $( eval $LS| grep -P "[\x00-\x1F]" ); do
printf "%-${LONGEST}s\t|%s\n" "$file" \
"$( echo $file | tr -d \\n\\r | tr -c [:print:] '\000' | sed s/'\x0'/"$TGT"/g )"
c=$(( $c + 1 ))
done
for file in $( eval $LS | grep -P "[\x80-\xFF]" ); do
printf "%-${LONGEST}s\t|%s\n" "$file" \
"$( echo $file | tr -d \\n\\r | tr -c [:print:] '\000' | sed s/'\x0'/"$TGT"/g )"
c=$(( $c + 1 ))
done
echo $c' matches. Sure?'
read i
for file in $( eval $LS | grep -P "[\x00-\x1F]" ); do
mv -iv -- "$file" "$( echo $file | tr -d \\n\\r | tr -c [:print:] '\000' | sed s/'\x0'/"$TGT"/g )"
done
for file in $( eval $LS | grep -P "[\x80-\xFF]" ); do
mv -iv -- "$file" "$( echo $file | tr -d \\n\\r | tr -c [:print:] '\000' | sed s/'\x0'/"$TGT"/g )"
done
exit
fi
if [ "$MODE" = "printf" ]; then
[[ -z "$TGT" ]] && helpexit
## string/number formatting
for file in $( eval $LS | grep -- "$SRC"); do [[ ${#file} -gt ${LONGEST} ]] && LONGEST=${#file}; done
printf "%-${LONGEST}s\t|%s\n" Matching Formatted
for file in $( eval $LS | grep -- "$SRC" )
do source_match=$( echo $file | grep -h -o -m 1 -- "$SRC" | head -n1 )
# remove zeroes from beginning, if matching integers
let source_match="10#$source_match" &> /dev/null
target_replace=$( printf "$TGT" "$source_match" ) || FORMATTING_ERROR=1
source_colored=$( echo $file | sed s/"\($SRC\)"/${HIGHLIGHTSRC}"\1"${RESET}/ )
target_colored=$( echo $file | sed s/"$SRC"/${HIGHLIGHTTGT}"${target_replace}"${RESET}/ )
length_diff=$(( ${#source_colored} - ${#file} ))
pad_length=$(( ${LONGEST} + ${length_diff} ))
printf "%-${pad_length}s\t|%s\n" "$source_colored" "$target_colored"
[[ "$FORMATTING_ERROR" -eq 1 ]] && exit 1
c=$(( $c + 1 ))
done
echo $c' matches. Sure?'
read i
for file in $( eval $LS | grep -- "$2" )
do source_match=$( echo $file | grep -h -o -m 1 -- "$SRC" | head -n1 )
# remove zeroes from beginning, if matching integers
let source_match="10#$source_match" &> /dev/null
target_replace=$( printf "$TGT" "$source_match" )
mv -iv -- "$file" "$( echo $file | sed s/"$SRC"/"${target_replace}"/ )"
done
exit
fi
## Normal regex replace
[[ -z "$SRC" ]] && helpexit
for file in $( eval $LS | grep -- "$SRC"); do [[ ${#file} -gt ${LONGEST} ]] && LONGEST=${#file}; done
printf "%-${LONGEST}s\t|%s\n" Matching Replaced
for file in $( eval $LS | grep -- "$SRC" ); do
source_colored=$( echo $file | sed s/"\($SRC\)"/${HIGHLIGHTSRC}"\1"${RESET}/$GLOBAL ) || ERROR=1
target_colored=$( echo $file | sed s/"$SRC"/${HIGHLIGHTTGT}"${TGT}"${RESET}/$GLOBAL ) || ERROR=1
length_diff=$(( ${#source_colored} - ${#file} ))
pad_length=$(( ${LONGEST} + ${length_diff} ))
printf "%-${pad_length}s\t|%s\n" "$source_colored" "$target_colored"
[[ "$ERROR" -eq 1 ]] && {
echo "Match='$SRC'"
echo "Replace='$TGT'"
exit 1
}
c=$(( $c + 1 ))
done
echo $c' matches. Sure?'
read i
for file in $( eval $LS | grep -- "$SRC" )
do mv -iv -- "$file" "$( echo $file | sed s/"$SRC"/"$TGT"/$GLOBAL )"
done