?? ren
字號:
let OPTIND=OPTIND-1shift $OPTINDoldpat=$1newpat=$2# If -m is given, a non-existant or null newpat should be set to oldpatif [ ${#ops[*]} -gt 0 ]; then case $# in 0) ;; 1) set -- "$oldpat" "$oldpat" newpat=$oldpat $debug && print -ru2 -- "Set new pattern to: $newpat" ;; *) if [ -z "$newpat" ]; then shift 2 set -- "$oldpat" "$oldpat" "$@" newpat=$oldpat $debug && print -ru2 -- "Set new pattern to: $newpat" fi ;; esacfi# Make sure input patterns that contain whitespace can be expanded properlyIFS=origPat=$oldpat# Generate list of filenames to act on.case $# in[01]) print -u2 "$Usage\nUse -h for help." exit 1 ;;2) if $recurse; then print -r -u2 "$name: No directory names given with -r. Use -h for help." exit 1 fi set -- $oldpat # Get list of all filenames that match 1st globbing pattern. if [[ ! -a $1 ]]; then $warnNoFiles && print -r -- "$name: No filenames match this pattern: $oldpat" exit fi ;;*) shift 2 ;;esacinteger patSegNum=1 numPatSegs# For old ksh# while [[ "$oldpat" = *'[\*\?]'* ]]; do# Example oldpat: foo*.a# Example newpat: bar*.b# Build list of non-pattern segments and globbing segments found in arguments.# Note the patterns given are used to get the list of filenames to act on,# to delimit constant segments, and to determine which parts of filenames are# to be replaced.# Examples given for first iteration (in the example, the only iteration)# The || newpat is to ensure that new pattern does not have more globbing# segments than old patternwhile [[ "$oldpat" = *@([\*\?]|\[+([!\]])\])* || "$newpat" = *@([\*\?]|\[+([!\]])\])* ]]; do ## Get leftmost globbing pattern in oldpat # Make r be oldpat with smallest left piece that includes a globbing # pattern removed from it r=${oldpat#*@([\*\?]|\[+([!\]])\])} # r=.a # Make pat be oldpat with the above removed from it, leaving smallest # left piece that includes a globbing pattern pat=${oldpat%%"$r"} # pat=foo* # Make l be pat with the globbing pattern removed from the right, # leaving a constant string l=${pat%@([\*\?]|\[+([!\]])\])} # l=foo # Remove the constant part of pat from the left, leaving the globbing # pattern pat=${pat#"$l"} # pat=* # Do the same thing for newpat, solely to provide a reliable test that # both oldpat & newpat contain exactly the same sequence of globbing # patterns. r=${newpat#*@([\*\?]|\[+([!\]])\])} # r=.b npat=${newpat%%"$r"} # pat=bar* l=${npat%@([\*\?]|\[+([!\]])\])} # l=bar npat=${npat#"$l"} # npat=* if [[ "$pat" != "$npat" ]]; then print -ru2 -- \"$name: Old-pattern and new-pattern do not have the same sequence of globbing chars.Pattern segment $patSegNum: Old pattern: $pat New pattern: $npat" exit 1 fi ## Find parts before & after pattern # oldpre[] stores the old constant part before the pattern, # so that it can be removed and replaced with the new constant part. oldpre[patSegNum]=${oldpat%%"$pat"*} # oldpre[1]=foo # oldsuf stores the part that follows the globbing pattern, # so that it too can be removed. # After oldpre[] & oldsuf[] have been removed from a filename, what remains # is the part matched by the globbing pattern, which is to be retained. oldsuf[patSegNum]=${oldpat#*"$pat"} # oldsuf[1]=.a # newpre[] stores the new constant part before the pattern, # so that it can be used to replace the old constant part. newpre[patSegNum]=${newpat%%"$pat"*} # newpre[1]=bar # Get rid of processed part of patterns oldpat=${oldpat#${oldpre[patSegNum]}"$pat"} # oldpat=.a newpat=${newpat#${newpre[patSegNum]}"$pat"} # newpat=.b # Store either * or ? in pats[], depending on whether this segment matches 1 # or any number of characters. [[ "$pat" = \[* ]] && pat=? pats[patSegNum]=$pat ((patSegNum+=1))doneif [ patSegNum -eq 1 ]; then print -u2 "No globbing chars in pattern." exit 1fioldpre[patSegNum]=${oldpat%%"$pat"*} # oldpre[2]=.aoldsuf[patSegNum]=${oldpat#*"$pat"} # oldsuf[2]=.anewpre[patSegNum]=${newpat%%"$pat"*} # newpre[2]=.bnumPatSegs=patSegNumif $debug; then patSegNum=1 while [[ patSegNum -le numPatSegs ]]; do print -ru2 -- \"Old prefix: <${oldpre[patSegNum]}> Old suffix: <${oldsuf[patSegNum]}> New prefix: <${newpre[patSegNum]}> Pattern: <${pats[patSegNum]}>" ((patSegNum+=1)) donefi# Example filename: foox.a# Example oldpat: foo*.a# Example newpat: bar*.binteger numFiles=0# Usage: renameFile filename [dirname]# [dirname] is a directory name to prefix filenames with when they are printed# for informational purposes.# Uses globals:# inclCt exclCt inclPats[] exclPats[] ops[]# numPatSegs oldpre[] oldsuf[] newpre[] pats[]# check warn tell verbose name# Modifies globals: numFilesfunction renameFile { typeset file=$1 subdir=$2 integer patSegNum patnum typeset origname porigname newfile matchtext pnewfile matchsegs integer startseg endseg origname=$file # origname=foox.a porigname=$subdir$file # Unfortunately, ksh88 does not do a good job of allowing for patterns # stored in variables. Without the conditional expression being eval'ed, # only sh patterns are recognized. If the expression is eval'ed, full # ksh expressions can be used, but then expressions that contain whitespace # break unless the user passed a pattern with the whitespace properly # quoted, which is not intuititive. This is fixed in ksh93; full patterns # work without being eval'ed. if [ inclCt -gt 0 ]; then patnum=0 while [ patnum -lt inclCt ]; do [[ "$file" = ${inclPats[patnum]} ]] && break ((patnum+=1)) done if [ patnum -eq inclCt ]; then $debug && print -ru2 -- "Skipping not-included filename '$porigname'" return 1 fi fi patnum=0 while [ patnum -lt exclCt ]; do if [[ "$file" = ${exclPats[patnum]} ]]; then $debug && print -ru2 -- "Skipping excluded filename '$porigname'" return 1 fi ((patnum+=1)) done # Extract matching segments from filename ((numFiles+=1)) patSegNum=1 while [[ patSegNum -le numPatSegs ]]; do # Remove a fixed prefix iteration: 1 2 file=${file#${oldpre[patSegNum]}} # file=x.a file= # Save the part of this suffix that is to be retained. To do this, we # need to know what part of the suffix matched the current globbing # segment. If the globbing segment is a *, this is done by removing # the minimum part of the suffix that matches oldsuf (since * matches # the longest segment possible). If the globbing segment is ? or [] # (the latter has already been coverted to ?), it is done by taking the # next character. if [ "${pats[patSegNum]}" == \? ]; then matchtext=${file#?} matchtext=${file%$matchtext} else matchtext=${file%${oldsuf[patSegNum]}} # matchtext=x matchtext= fi $debug && print -ru2 -- "Matching segment $patSegNum: $matchtext" file=${file#$matchtext} # file=.a file=.a matchsegs[patSegNum]=$matchtext ((patSegNum+=1)) done # Paste fixed and matching segments together to form new filename. patSegNum=0 newfile= while [[ patSegNum -le numPatSegs ]]; do matchtext=${matchsegs[patSegNum]} startseg=patSegNum if [ -n "${ops[startseg]}" ]; then endseg=${op_end_seg[startseg]} while [ patSegNum -lt endseg ]; do ((patSegNum+=1)) matchtext=$matchtext${matchsegs[patSegNum]} done if [[ "$matchtext" != +([-0-9]) ]]; then print -ru2 -- \"Segment(s) $startseg - $endseg ($matchtext) of file '$porigname' do not form an integer; skipping this file." return 2 fi i=$matchtext let "j=${ops[startseg]}" || { print -ru2 -- \"Operation failed on segment(s) $startseg - $endseg ($matchtext) of file '$file'; skipping this file." return 2 } $debug && print -ru2 -- "Converted $matchtext to $j" matchtext=$j fi newfile=$newfile${newpre[startseg]}$matchtext # newfile=barx newfile=barx.b ((patSegNum+=1)) done pnewfile=$subdir$newfile if $check && [ -e "$newfile" ]; then $warn && print -ru2 -- "$name: Not renaming \"$porigname\"; destination filename \"$pnewfile\" already exists." return 2 fi if $tell; then print -n -r -- "Would move: $porigname -> $pnewfile" $warn && [ -e "$newfile" ] && print -n -r " (destination filename already exists; would replace it)" print "" else if $verbose; then print -n -r -- "Moving: $porigname -> $pnewfile" $warn && [ -e "$newfile" ] && print -n -r -- " (replacing old destination filename \"$pnewfile\")" print "" elif $warn && [ -e "$newfile" ]; then print -r -- "$name: Note: Replacing old file \"$pnewfile\"" fi mv -f -- "$origname" "$newfile" fi}if $recurse; then oPWD=$PWD find "$@" -depth -type d ! -name '**' -print | while read dir; do cd -- "$oPWD" if cd -- "$dir"; then for file in $origPat; do renameFile "$file" "$dir/" done else print -ru2 -- "$name: Could not access directory '$dir' - skipped." fi doneelse for file; do renameFile "$file" donefiif [ numFiles -eq 0 ]; then $warnNoFiles && print -ru2 -- \ "$name: All filenames were excluded by patterns given with -p or -P."fi
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -