다른 위치의 파일 이름을 비교하는 bash 스크립트가 있습니다. 파일 이름에는 두 가지 다른 인코딩으로 된 특수 문자가 있으므로 내 스크립트가 해당 특정 파일과 일치하지 않습니다.
Bash가 일치하도록 할 수 있는 방법이 있나요?
이는 각각 utf8 및 TIS-620 샘플 파일 이름으로 인코딩됩니다 Löffler
.Löffler
스크립트 예:
for i in /dir1/*; do
if [ ! -h "$i" ]; then
[ -d "/dir2/${i##*/}" ]
fi
사용우넘다음 정보를 얻을 수 있습니다.
ö utf8 버전
Octal Decimal Hex HTML Character Unicode
0366 246 0xF6 ö "ö" LATIN SMALL LETTER O WITH DIAERESIS
TIS-620 버전ö
Octal Decimal Hex HTML Character Unicode
0157 111 0x6F o "o" LATIN SMALL LETTER O
01410 776 0x308 ̈ "̈" COMBINING DIAERESIS
편집하다:
불일치를 일으키는 첫 번째 원인은 UTF 정규화를 사용하는 도구였습니다. 다른 인코딩에서 동일한 문자를 일치시키는 방법을 알고 싶습니다. 다르게 말하면 BASH 스크립트와 함께 UTF 정규화 인라인을 어떻게 사용합니까?
답변1
인코딩에서 일부 "텍스트"를 비교해야 한다고 생각합니다.TIS-620의 코드 페이지(태국어) ~와utf8 인코딩(유니버설) 동등.
음, 가장 보편적인 인코딩(UTF-32만큼 많은 문자를 인코딩함)은 utf8이므로 가장 기본 인코딩인 TIS-620을 utf8로 변환해야 합니다.
일반적으로 사용되는 인코딩 변환 도구는 다음과 같습니다.iconv
. 이 도구를 사용하면 다음을 수행할 수 있습니다.
$ printf '\xC1' | iconv -f TIS620 -t utf8
ม
터미널이 utf8을 허용하는 경우 ม 문자를 확인하세요. 이 역할 ม
의 값은 C1
Wikipedia의 TIS-620 표에서 찾을 수 있습니다.
또는 문자를 구성하는 바이트를 "참조"(utf8 형식):
$ printf '\xC1' | iconv -f TIS620 -t utf8 | od -vAn -tx1
e0 b8 a1
유니코드 코드 포인트 번호를 사용하여 문자를 인코딩할 때 생성되는 3바이트는 무엇입니까?U0E21
파일 형식에서아니면, 또한웹사이트: www.utf8-chartable.de:
U+0E21 ม e0 b8 a1 THAI CHARACTER MO MA
iconv에서 TIS620에 사용할 수 있는 인코딩 목록은 다음과 같습니다.
$ iconv -l | grep 620
TIS-620//
TIS620-0//
TIS620.2529-1//
TIS620.2533-0//
TIS620//
파일 이름 인코딩과 일치하는 것을 선택하세요.
그러나 찾을 수 없습니다.움라우트 ö태국어.
이것태국 TIS620 페이지
아니면 (아주 오래된)ISO/IEC 10646-1:1993으로 태국어 번역태국어에 움라우트 o가 있음을 표시하지 마세요.
질문을 다시 편집할 수 있나요?
모음에 대하여
콘솔/터미널이 utf8을 이해하도록 구성되었다고 가정합니다. 그리고 디렉터리에 서로 다른 발음 구별 부호를 사용하여 세 개의 파일 이름을 만들어 보겠습니다.
라틴어 ö(유니코드 코드 포인트)(utf8에서 0xC3 0xB6으로 표시됨).
분음 기호가 있는 라틴 소문자 O(U+00F6)
라틴뇌$ printf 'L\xC3\xB6ffler'; echo Löffler
라틴어 ö(문자 o 다음에 분음 기호가 옴)(utf8에서는 0x6F 0xCC 0x88).
결합된 부분 방법(U+0308)
부분적인 톤$ printf 'Lo\xCC\x88ffler'; echo Löffler
및: 분음 기호가 있는 키릴 문자 o(utf-8에서는 0xD3 0xA7)
분음 기호가 있는 키릴 소문자 O(U+04E7)
분음 부호가 있는 키릴 문자 O$ printf 'L\xD3\xA7ffler'; echo Lӧffler
이러한 파일 이름으로 세 개의 파일을 만들려면 다음을 사용합니다.
$ touch $(printf 'L\xC3\xB6ffler Lo\xCC\x88ffler L\xD3\xA7ffler')
이러한 파일을 나열하는 한 가지 방법은 일치하는 glob(해당 파일만)을 사용하는 것입니다.
이 경우 ffler
모든 파일에 후행이 나타납니다.
$ echo *ffler
Löffler Löffler Lӧffler
이 에코의 결과는 다음을 통해 자세히 볼 수 있습니다.
$ echo *ffler | od -vAn -tx1c
4c 6f cc 88 66 66 6c 65 72 20 4c c3 b6 66 66 6c
L o 314 210 f f l e r L 303 266 f f l
65 72 20 4c d3 a7 66 66 6c 65 72 0a
e r L 323 247 f f l e r \n
이것은 단지 모든 사람이 다르다는 사실을 반영합니다.
쉘의 위치 매개변수에 할당된 경우:
$ set -- $(echo *ffler)
각 항목을 비교할 수 있습니다.
[ "$1" == "$2" ] && echo "Diferent" || echo "Equal"
그러나 첫 번째와 두 번째가 동일하다고 예상하는 것이 합리적입니다.
하지만 차이점은"구성"을 완성하는 방법. NFC(통합) 형식을
사용합니다 . NFD(분해) 형태를 사용합니다 .'L\xC3\xB6ffler'
'Lo\xCC\x88ffler'
uconv(icu-devtools 패키지에서) 이 두 형식 사이를 변환합니다.
분해된 형태:
$ echo *ffler | uconv -x any-nfd | od -vAn -tx1c
4c 6f cc 88 66 66 6c 65 72 20 4c 6f cc 88 66 66
L o 314 210 f f l e r L o 314 210 f f
6c 65 72 20 4c d0 be cc 88 66 66 6c 65 72 0a
l e r L 320 276 314 210 f f l e r \n
사전 조립된 형태:
$ echo *ffler | uconv -x any-nfc | od -vAn -tx1c
4c c3 b6 66 66 6c 65 72 20 4c c3 b6 66 66 6c 65
L 303 266 f f l e r L 303 266 f f l e
72 20 4c d3 a7 66 66 6c 65 72 0a
r L 323 247 f f l e r \n
이제 이 값을 위치 매개변수로 설정하고 비교하면 다음과 같습니다.
$ set -- $( echo *ffler | uconv -x any-nfc | od -vAn -tx1c )
$ [ "$1" == "$2" ] && echo "Diferent" || echo "Equal"
키릴 문자는 그러한 구성 형식과 동의어가 아닙니다.
이름을 다른 이름과 비교할 수 있도록 변환해야 하는 경우 멀티바이트 문자를 이해하는 도구가 필요합니다.
$ echo *ffler | sed 's/\xd3\xa7/\xc3\xb6/g' | od -vAn -tx1c
4c 6f cc 88 66 66 6c 65 72 20 4c c3 b6 66 66 6c
L o 314 210 f f l e r L 303 266 f f l
65 72 20 4c c3 b6 66 66 6c 65 72 0a
e r L 303 266 f f l e r \n
NFC 형식에서만 작동합니다.
$ echo *ffler | uconv -x any-nfc | sed 's/\xd3\xa7/\xc3\xb6/g' | od -vAn -tx1c
4c c3 b6 66 66 6c 65 72 20 4c c3 b6 66 66 6c 65
L 303 266 f f l e r L 303 266 f f l e
72 20 4c c3 b6 66 66 6c 65 72 0a
r L 303 266 f f l e r \n
이제 세 이름은 정확히 동일합니다.
위의 내용으로 귀하의 실제 우려 사항이 명확해졌습니까?
아직도 가까워요?