macOS에서 악센트로 파일 이름을 바꾸는 방법은 무엇입니까?

macOS에서 악센트로 파일 이름을 바꾸는 방법은 무엇입니까?

"à" 문자가 포함된 파일의 이름을 바꾸려고 합니다.

나는 다음을 수행합니다.

rename -v 's/à/a/g' *

그러나 모든 파일이 변경되지 않았음을 보여줍니다. Verbose 모드에서는 동일한 내용이 표시됩니다.

탈출을 시도했지만 \실패했습니다.

정규 표현식이 이 유형의 문자와 일치하도록 하려면 어떻게 해야 합니까?

편집하다

출력 perl -V:

Summary of my perl5 (revision 5 version 18 subversion 2) configuration:

  Platform:
    osname=darwin, osvers=16.0, archname=darwin-thread-multi-2level
    uname='darwin osx320.apple.com 16.0 darwin kernel version 15.0.0: wed jun 22 17:57:08 pdt 2016; root:xnu-3247.1.106.2.9~1development_x86_64 x86_64 '
    config_args='-ds -e -Dprefix=/usr -Dccflags=-g  -pipe  -Dldflags= -Dman3ext=3pm -Duseithreads -Duseshrplib -Dinc_version_list=none -Dcc=cc'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-arch x86_64 -arch i386 -g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -fstack-protector',
    optimize='-Os',
    cppflags='-g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -fstack-protector'
    ccversion='', gccversion='4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc -mmacosx-version-min=10.12.5', ldflags ='-arch x86_64 -arch i386 -fstack-protector'
    libpth=/usr/lib /usr/local/lib
    libs= 
    perllibs=
    libc=, so=dylib, useshrplib=true, libperl=libperl.dylib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-arch x86_64 -arch i386 -bundle -undefined dynamic_lookup -fstack-protector'


Characteristics of this binary (from libperl): 
  Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
                        PERL_DONT_CREATE_GVSV
                        PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                        PERL_PRESERVE_IVUV PERL_SAWAMPERSAND USE_64_BIT_ALL
                        USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
                        USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE
                        USE_LOCALE_NUMERIC USE_PERLIO USE_PERL_ATOF
                        USE_REENTRANT_API
  Locally applied patches:
    /Library/Perl/Updates/<version> comes before system perl directories
    installprivlib and installarchlib points to the Updates directory
  Built under darwin
  Compiled at Feb  6 2017 22:16:22
  @INC:
    /Library/Perl/5.18/darwin-thread-multi-2level
    /Library/Perl/5.18
    /Network/Library/Perl/5.18/darwin-thread-multi-2level
    /Network/Library/Perl/5.18
    /Library/Perl/Updates/5.18.2
    /System/Library/Perl/5.18/darwin-thread-multi-2level
    /System/Library/Perl/5.18
    /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.18
    .

편집 2:

출력 locale:

LANG=
LC_COLLATE="C"
LC_CTYPE="UTF-8"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=

해결책

간단히 말해서 이것이 작동하는 것입니다. 세 가지 솔루션이 모두 작동했습니다.

  1. rename -nv $'s/a\xcc\x80/a/g' *
  2. PERL_UNICODE=AS rename -n 's/\pM//g' ./*. (선택한 답변의 설명 참조)
  3. zsh대신 MacOS의 기본 셸( ) 로 전환하면 bash원래 명령(예: 결합 문자를 지정하지 않음 a\u300)이 작동합니다 rename -v 's/à/a/g' *.

이러한 해결 방법 중 만족스럽지 못한 경우 선택한 답변을 확인하여 유용한 팁을 찾아보세요.

답변1

macOS 및 최소한 HFS+ 파일 시스템에서 악센트 문자는 분해된 형식으로 인코딩되므로 à인코딩은 a\u300( a다음에 옵니다.심각한 악센트와 결합 문자 결합)은 다양한 오류를 발생시킵니다( touch $'\ue0'aLinus Torvald의 유명한 호언장담 중 하나) 의사 대소 문자를 구분하지 않는 것이 좋습니다.

이렇게 하면 다음 사항을 알 수 있습니다.

touch à; echo ?

한 문자로 구성된 파일 이름을 나열하려면 아무것도 반환하지 않습니다.

echo ??

또는

echo *a*

값을 반환합니다 à(실제로는 ). 그리고:

$ echo ?? | uconv -x name
\N{LATIN SMALL LETTER A}\N{COMBINING GRAVE ACCENT}\N{<control-000A>}

따라서 다음이 필요합니다.

rename $'s/a\u300/a/g' ./*

zsh( 호환되는 쉘을 가정 ). 또는 ksh93 $'...'따옴표는 지원하지만 '는 지원하지 않는 쉘(예: zshmacOS의 $'\u300'고대 버전 ) 에 대해 U+0300 문자(0xcc 0x80)의 UTF-8 인코딩을 수동으로 지정합니다 .bash

rename $'s/a\xcc\x80/a/g' ./*

또는 perl다음 \xcc\x80시퀀스를 직접 해석하십시오.

rename 's/a\xcc\x80/a/g' ./*

또는 유니코드 문자:

PERL_UNICODE=AS rename 's/\x{300}//' ./*

또는 모든 결합 문자를 제거하십시오.

PERL_UNICODE=AS rename -n 's/\pM//g' ./*

거기에서 우리는 perl고려해야 할 매개변수 ASUTF-8로 인코딩될 tdio 스트림( perldoc perlrun이 옵션과 동등한 환경 변수에 대한 설명 참조)을 지시하고 ark 유니코드 속성(또는의 약자, 참조)이 있는 모든 문자를 제거하도록 지시합니다. 세부)$PERL_UNICODE-CMp\pM\p{Mark}\p{Combining_Mark}perldoc perluniprops

zsh다음을 통해 파일을 나열 할 수 있어야 합니다 .

ls -d $'a\u300'

그리고:

ls -d $'\ue0'

( 대소문자를 구분하지 않기 $'A\u300' and possibly $'\uc0때문에 À) 그러나:

ls -d *A*

다음 이외의 쉘 zsh:

ls -d *$'\ue0'*
ls -d *$'\xc3\xa0'*

쉘은 현재 디렉토리의 내용을 나열하고 각 파일 이름에 패턴을 적용하며 파일 이름은 a\u300일치하지 않는 것으로 인코딩되기 때문에 일치하지 않습니다.

그러나 zshmacOS에서만 셸은 악센트를 결합하여 이러한 문자를 readdir()마치 iconv -f UTF-8-MAC -t UTF-8.자체 내부 zreaddir()포장readdir()다른 곳 에서는 작동하지 않는 aU+0300이유를 설명하는 대신 U+00E0을 반환합니다 .echo *à*echo *a*

이 변경 사항은 2014년 6월에 출시되었습니다. 보다더 자세한 내용은 zsh 메일링 리스트에서 논의하세요..

문제의 핵심은 사용자 입력에 사용되는 인코딩과 파일 시스템에 파일 이름을 저장(및 나열)하는 데 사용되는 인코딩 간의 차이에 있습니다. 거의 모든 캐릭터가 미리 조립되고 분해된 형태를 가지고 있는 한국어에서는 문제가 훨씬 더 심각합니다. 이는 zsh 문제가 원래 한국인에 의해 제기된 이유를 설명합니다.

그래서 zsh기본적으로수리하다파일 시스템에서 Apple의 분해 형식 선택이 좋지 않으므로 완성 및 와일드카드를 사용할 수 있지만 불행히도 이는 그렇지 않은 경우에만 작동하고 그렇지 않으면 zsh여전히 작동하지 않습니다.ls | grep àfind . -name '*à*'

관련 정보