ä
디렉터리 이름과 파일 이름에 일부 "특수" 문자( , ö
, ü
) 가 포함된 Debian 시스템에 깊은 폴더 구조가 있습니다 . 그러나 이는 "ISO-8859-1"이 아니라 유니코드 결합 문자 형태입니다. 내가 아는 한, a
두 개의 점(분음 부호/움라우트)을 "별도의" 문자로 추가하는 것은 간단한 문제입니다.
find 및 sed를 사용하여 모든 파일과 폴더의 이름을 일괄적으로 변경해 보았습니다.
#!/bin/bash
# Files - normal characters
find . -depth -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;
# Files - Unicode combining characters
find . -depth -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;
# Directories - normal characters
find . -depth -type d -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;
# Directories - Unicode combining characters
find . -depth -type d -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;
그러나 인수의 매개변수가 ISO-8859-1 대신 유니코드로 결합된 경우 파일/폴더 이름에 find
나타나는 모든 항목 도 선택된 것으로 보입니다. 예를 들어,a
ä
-name
ä
$ find . -name "*[ä]*" //<-- one letter ä
./filename_one_letter_ä
$ find . -name "*[ä]*" //<-- combining letter ä
./filename_with_just_a
./filename_one_letter_ä
./filename_with_combining_diaeresis_ä
따라서 sed
파일 이름을 변경하지 않고 전달하므로 예를 들어 " "에서 " "로 mv
이름을 바꾸도록 요청할 때 불평합니다 (즉, 소스와 대상이 동일함).Baustand
Baustand
find를 사용하여 검색할 수 없는 경우 Linux 시스템의 파일/폴더 구조에서 유니코드 ä
, ö
, ü
, Ä
, 의 모든 조합을 검색하고 바꾸는 방법은 무엇입니까 Ö
? Ü
시도해 볼 수 있는 다른 방법이 있나요?
내 파일 및 디렉터리 이름의 예는 다음과 같습니다.
/Projekte/03-11_Törggel_Mammern/Baustand/03-11_Törggel-Baustand_190501_0009.jpg
이름을 다음으로 바꾸고 싶습니다.
/Projekte/03-11_Toerggel_Mammern/Baustand/03-11_Toerggel-Baustand_190501_0009.jpg
출력 echo $LANG
은 입니다 en_US.UTF-8
.
답변1
이 ATM을 재현(또는 테스트)할 수는 없지만...
글쎄, 당신은 [xyz]
일치를 알고 있습니다.x
또는 y
또는 z
. 내 생각에 당신이 (결합 문자를 사용하여) 말할 때 [äöü…]
그것은 보고 있는 것 같아요
a
- (결합하다)
¨
o
- (결합하다)
¨
u
- (결합하다)
¨
- …
a
따라서 이름에 , o
, 가 포함된 파일을 찾습니다 .u
또는(조합) ¨
, 반드시 그런 것은 아니지만 ä
, ö
또는 ü
.
따라서 별도로 찾아보십시오.
find . -depth -name "*ä*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/ä/ae/g")"' _ {} ';'
find . -depth -name "*ö*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/ö/oe/g")"' _ {} ';'
find . -depth -name "*ü*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/ü/ue/g")"' _ {} ';'
find . -depth -name "*Ä*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/Ä/Ae/g")"' _ {} ';'
find . -depth -name "*Ö*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/Ö/Oe/g")"' _ {} ';'
find . -depth -name "*Ü*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/Ü/Ue/g")"' _ {} ';'
(대괄호 제외). 일부 파일 이름에서는 (따옴표 제외) 이 echo $1
실패할 수 있습니다. ( ';'
동등함 \;
; 스타일상 백슬래시를 피하는 것을 선호합니다.)
아니면 당신이진짜진짜하나의 명령으로 모든 작업을 수행하려면 다음을 시도하십시오.
find . -depth "(" -name "*ä*" -o -name "*ö*" -o -name "*ü*" \
-o -name "*Ä*" -o -name "*Ö*" -o -name "*Ü*" ")" \
-exec bash -c 'mv "$1" "$(printf "%s" "$1" | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} ';'
( printf "%s"
기능적으로는 과 매우 유사 echo
하지만 더 안전합니다. 스타일적으로는 일반적으로 (작은 따옴표 포함)을 사용합니다 . 여기서는 작은 따옴표( ) 문자열 안에 printf '%s'
있기 때문에 큰 따옴표를 사용합니다 .)'mv …'
가능한
… "(" -iname "*ä*" -o -iname "*ö*" -o -iname "*ü*" ")" …
작동합니다.
LANG
또한 처음에 시도한 작업을 로 설정하면 작동할 수도 있습니다 de_DE.UTF-8
.
답변2
이것de-ASCII
음역uconv
당신이 원하는 것을 할 것 입니다. 예를 들어 사전 구성 및 분해된 문자와 대문자 및 소문자 버전은 다음과 같습니다 ä
.
$ printf '\u00c4 \u00e4 A\u0308 a\u0308\n'
Ä ä Ä ä
$ printf '\u00c4\u00e4A\u0308a\u0308' | uconv -x name
\N{LATIN CAPITAL LETTER A WITH DIAERESIS}\N{LATIN SMALL LETTER A WITH DIAERESIS}\N{LATIN CAPITAL LETTER A}\N{COMBINING DIAERESIS}\N{LATIN SMALL LETTER A}\N{COMBINING DIAERESIS}
$ printf '\u00c4\u00e4A\u0308a\u0308 \u00c4 A\u0308 \u00c4B\n' | uconv -x de-ASCII
AeaeAeae AE AE AEB
(또한 상황에 따라 Ä
"또는"으로 변경되는 점 에 유의하세요).AE
Ae
따라서 여기에서 다음과 같은 것을 사용하여 이름에 ASCII가 아닌 문자가 포함된 모든 파일을 변환해 볼 수 있습니다(zsh에서).
autoload zmv
zmv -n $'(**/)(*[^\1-\177]*)' '$1$(print -rn -- $2 | uconv -x de-ASCII)'
예:
$ touch $'\u00c4\u00e4A\u0308a\u0308'
$ touch $'St\ue9phane' $'Ste\u301phane'
$ zmv -n $'(**/)(*[^\1-\177]*)' '$1$(print -rn -- $2 | uconv -x de-ASCII)'
mv -- ÄäÄä AeaeAeae
mv -- Stéphane Stephane
mv -- Stéphane Stephane
만족스러우면 삭제 -n
(테스트 실행)합니다.
또는 uconv
이름을 바꿔야 하는 파일이 수백만 개 있는 경우를 대비하여 파일당 하나씩 실행하지 마세요.
files=(**/*[^$'\1-\177']*)
typeset -U basenames=($files:t)
typeset -A translation
print -rNC1 -- $basenames | uconv -x de-ASCII |
for name in $basenames; do
IFS= read -rd '' translated && translation[$name]=$translated
done
zmv -n $'(**/)(*[^\1-\177]*)' '$1${translation[$2]-$2}'
분해된 형태의 분음 문자가 포함된 파일을 찾는 방법에 대한 보다 일반적인 질문에 대한 대답으로 결합된 분음 문자(U+308)만 찾으면 됩니다.
그래서:
find . -name $'*\u0308*'
또는 AOUaou 중 하나만 따라야 하는 경우:
find . -name $'*[AOUaou]\u0308*'
사전 결합된 형태의 경우 별도로 나열해야 합니다.
find . -name '*[ÄËÏÖÜäëïöüÿŸǕǖǗǘǙǚǛǜǞǟȪȫ΅ΐΪΫΰϊϋϔӒӓӚӛӜӝӞӟӤӥӦӧӪӫӬӭӰӱӴӵӸӹḦḧḮḯṎṏṲṳṺṻẄẅẌẍẗ⍡⍢⍣⍤⍥⍨⍩⸚]*'
또는:
find . -name $'*[\uA8\uC4\uCB\uCF\uD6\uDC\uE4\uEB\uEF\uF6\uFC\uFF\u178\u1D5\u1D6\u1D7\u1D8\u1D9\u1DA\u1DB\u1DC\u1DE\u1DF\u22A\u22B\u385\u390\u3AA\u3AB\u3B0\u3CA\u3CB\u3D4\u4D2\u4D3\u4DA\u4DB\u4DC\u4DD\u4DE\u4DF\u4E4\u4E5\u4E6\u4E7\u4EA\u4EB\u4EC\u4ED\u4F0\u4F1\u4F4\u4F5\u4F8\u4F9\u1E26\u1E27\u1E2E\u1E2F\u1E4E\u1E4F\u1E72\u1E73\u1E7A\u1E7B\u1E84\u1E85\u1E8C\u1E8D\u1E97\u2361\u2362\u2363\u2364\u2365\u2368\u2369\u2E1A]*'
$'\uXXXX'
bash를 포함한 일부 다른 쉘은 이제 zsh를 사용한 표기법을 지원합니다.