'사례 중복' 일괄 이름 바꾸기

'사례 중복' 일괄 이름 바꾸기

이 질문과 답변에 대해:https://unix.stackexchange.com/a/188020/189709

for f in *; do mv --backup=numbered -- "$f" "${f,,}"; done
rename -v -- 's/\.~(\d+)~/$1/' *.~*~

mv: 이 명령은 모든 파일 이름을 암시적으로 소문자로 변경합니다. 이 작업을 수행하지 않도록 옵션을 어떻게 수정합니까? 백업 번호는 파일을 구별하기에 충분합니다.

이름 바꾸기: test.~1~ test1 파일이 이미 존재하는 경우 이름이 바뀌지 않습니다. test.~1~의 이름을 test2로 바꾸는 옵션을 어떻게 변경합니까?

답변1

mv보고 있는 코드는 실제 파일 이름 충돌 시 중복 항목을 잡기 위해 호출 시 파일 이름을 명시적으로 소문자로 지정하므로 이름 바꾸기 정책을 직접 구현하는 것이 좋습니다 .

다음은 실제로 충돌을 일으키지 않고 충돌이 있는 경우에만 파일 이름을 바꿉니다(즉, 충돌을 처리하기 위해 GNU로 돌아가지 않습니다 mv).

#!/bin/bash

# The suffix array contains a filename suffix (a positive integer)
# for each lower-cased filename.
declare -A suffix

# Get all names in the current directory.
set -- *

# Initialise the suffixes for each existing name to zero.
for name do
        suffix[${name,,}]=0
done

for name do

        # Loop until no name collision.
        while true; do
                # Get the current suffix for this filename.
                suf=${suffix[${name,,}]}

                # Increment the suffix for this filename.
                suffix[${name,,}]=$(( ${suffix[${name,,}]} + 1 ))

                # If the suffix is 0, empty it.
                [[ $suf == 0 ]] && suf=

                # Create the new name.
                newname=$name$suf

                # Break out of the loop if the name didn't change, or if
                # there's no other file that has this name.
                if [[ $name == "$newname" ]] ||
                   [[ -z ${suffix[${newname,,}]} ]]
                then
                        break
                fi
        done

        if [[ $name != "$newname" ]]; then
                printf '%s --> %s\n' "$name" "$newname"
                # uncomment the next line to actually do the renaming
                # mv -- "$name" "$newname"
        else
                printf '%s unchanged\n' "$name"
        fi

done

(주석 처리된 부분을 참고하세요 mv. 올바른 작업을 수행한다는 확신이 들 때까지 해당 줄을 주석 처리한 상태로 실행하는 것이 좋습니다.)

시험:

$ ls
A         Bb        TEST1     a         bb        test
BB        TEST      Test      bB        script.sh
$ bash script.sh
A unchanged
BB unchanged
Bb --> Bb1
TEST unchanged
TEST1 unchanged
Test --> Test2
a --> a1
bB --> bB2
bb --> bb3
script.sh unchanged
test --> test3

관련 정보