From 017e292e50d92ba311e6fa9aafcc243804564c5b Mon Sep 17 00:00:00 2001 From: Ville Rantanen Date: Mon, 23 May 2016 14:00:09 +0300 Subject: [PATCH] restructuring mvregex --- files/mvregex | 157 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 127 insertions(+), 30 deletions(-) diff --git a/files/mvregex b/files/mvregex index 29c9d6f..ea69b0f 100755 --- a/files/mvregex +++ b/files/mvregex @@ -1,37 +1,134 @@ #!/bin/bash function helpexit() { - echo rename files in current folder replacing arg1 with arg2. - echo '-n for match non ascii, replace with arg2' + 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 } - -IFS=$'\n' [[ -z "$1" ]] && helpexit -[[ "$1" = "-h" ]] && helpexit - -POSTPROC="sed 's, , -> ,'" -which ncsv &>/dev/null && POSTPROC="ncsv -c" -c=0 -if [ "$1" = "-n" ] -then for file in $( ls | grep -P "[\x80-\xFF]" ) - do echo "$file" '->' "$( echo $file | tr -d \\n\\r | tr -c [:print:] '\000' | sed s/'\x0'/"$2"/g )" - c=$(( $c + 1 )) - done - echo $c' matches. Sure?' - read i - for file in $( ls | grep -P "[\x80-\xFF]" ) - do mv -iv -- "$file" "$( echo $file | tr -d \\n\\r | tr -c [:print:] '\000' | sed s/'\x0'/"$2"/g )" - done - exit -fi -( -echo -e "Matching\tReplaced" -for file in $( ls | grep -- "$1" ) -do echo -e "$file"\\t"$( echo $file | sed s/"$1"/"$2"/g )" -done ) | eval $POSTPROC | grep --color=always -E "$1|$" -echo 'Sure?' -read i -for file in $( ls | grep -- "$1" ) -do mv -iv -- "$file" "$( echo $file | sed s/"$1"/"$2"/g )" +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