programing

RE 오류: Mac OS X에서 잘못된 바이트 시퀀스

oldcodes 2023. 4. 19. 23:26
반응형

RE 오류: Mac OS X에서 잘못된 바이트 시퀀스

Mac OS X의 Make file에서 iOS로 교차 컴파일하기 위해 문자열을 바꾸려고 합니다.문자열에는 이중 따옴표가 포함되어 있습니다.명령어는 다음과 같습니다.

sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure

오류는 다음과 같습니다.

sed: RE error: illegal byte sequence

큰따옴표, 쉼표, 대시, 콜론에서 벗어나려고 노력했지만 재미없었다.예를 들어 다음과 같습니다.

sed -i "" 's|\"iphoneos-cross\"\,\"llvm-gcc\:\-O3|\"iphoneos-cross\"\,\"clang\:\-Os|g' Configure

나는 그 문제를 디버깅하느라 애를 먹고 있다.어떻게 해야 하는지 아는 사람?sed잘못된 바이트 시퀀스의 위치를 인쇄할 수 있습니까?아니면 불법 바이트 시퀀스가 뭔지 아는 사람?

증상을 나타내는 명령어 예시:sed 's/./@/' <<<$'\xfc'바이트가 원인이 되어 실패한다.0xfc유효한 UTF-8 문자가 아닙니다.
반면 GNU는 sed(Linux, 그러나 MacOS에도 설치 가능) 오류 보고 없이 잘못된 바이트만 전달합니다.

이전에 받아들여진 답변을 사용하는 것은, 실제의 로케일에 대한 서포트를 잃는 것에 개의치 않는 옵션입니다(미국 시스템상에서 외국 문자를 취급할 필요가 없는 경우는, 그것도 괜찮습니다).

, 동일한 효과를 얻을있는 것은 단일 명령어뿐입니다.

LC_ALL=C sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure

주의: 중요한 것은 효과적입니다. LC_CTYPE의 설정C,그렇게LC_CTYPE=C sed ...통상은 동작합니다만, 만약LC_ALL우연히 (다른 것에) 설정되다C개인을 덮어씁니다.LC_*- 다음과 같은 범주 변수LC_CTYPE따라서, 가장 강력한 접근법은 다음을 설정하는 것이다.LC_ALL.

단, (유효한) 설정LC_CTYPE로.C는, OS X 가 디폴트로 채용하고 있는 멀티바이트 온디맨드 UTF-8 인코딩관계없이, 각 바이트가 독자적인 문자처럼 취급합니다(부호화 규칙에 근거한 해석은 실행되지 않습니다).이 경우, 외부 문자는 멀티바이트 인코딩을 사용합니다.

즉, 과 유틸리티가 기본적인 영문자(7비트 ASCII 범위의 영문자)만을 문자로 인식하도록 설정하면 외부 문자가 문자로 취급되지 않기 때문에 예를 들어 대/소문자 변환이 실패합니다.

다시 말씀드리지만 다음과 같이 멀티바이트로 인코딩된 문자와 일치할 필요가 없는 경우에도 괜찮습니다.é이러한 문자를 통과시키고 싶을 뿐입니다.

이것이 불충분하거나 원래의 에러의 원인(문제의 원인이 된 입력 바이트의 특정 포함)을 파악해, 필요에 따라서 부호화 변환을 실행하는 경우는, 이하를 참조해 주세요.


문제는 입력 파일의 인코딩이 셸의 인코딩과 일치하지 않는다는 것입니다.
좀 더 구체적으로 말하면, 입력 파일에는 UTF-8에서는 유효하지 않은 방식으로 인코딩된 문자가 포함되어 있습니다(@Klas Lindbeck가 코멘트로 기술한 바와 같이).sed가, 에러 메세지가 에러 메세지로 .invalid byte sequence.

대부분의 경우 입력 파일은 다음과 같은 싱글바이트 8비트 인코딩을 사용합니다.ISO-8859-1는 "서유럽" 언어를 인코딩하는 데 자주 사용됩니다.

예:

가 있는 편지à에는 Unicode 포인트 Unicode 가 .0xE0- (224)와 - 와 (ISO-8859-1단, UTF-8 인코딩의 특성상 이 단일 코드 포인트는 2바이트로 표시됩니다.0xC3 0xA0단, 1바이트를 전달하려고 합니다. 0xE0UTF-8에서는 무효입니다.

다음은 문자열을 사용한 문제의 시연입니다.voilà「」로됩니다.ISO-8859-1à(ANSI-C 따옴표로 둘러싸인 bash 스트링에 의해) 1바이트로 표시됩니다.$'...')를 사용하는 \x{e0}바이트를 작성한다).

에 주의:sed명령어는 사실상 입력을 통과시키는 no-op이지만 오류를 유발하려면 이 명령어가 필요합니다.

  # -> 'illegal byte sequence': byte 0xE0 is not a valid char.
sed 's/.*/&/' <<<$'voil\x{e0}'

문제를 간단히 무시하기 위해, 위와 같이LCTYPE=C어프로치를 사용할 수 있습니다.

  # No error, bytes are passed through ('á' will render as '?', though).
LC_CTYPE=C sed 's/.*/&/' <<<$'voil\x{e0}'

문제의 원인이 되고 있는 입력 부분을 특정하려면 , 다음의 순서에 따릅니다.

  # Convert bytes in the 8-bit range (high bit set) to hex. representation.
  # -> 'voil\x{e0}'
iconv -f ASCII --byte-subst='\x{%02x}' <<<$'voil\x{e0}'

출력에는 하이비트세트(7비트 ASCII 범위를 넘는 바이트)를 가진 모든 바이트가 16진수 형식으로 표시됩니다.(단, 여기에는 올바르게 인코딩된 UTF-8 멀티바이트 시퀀스도 포함되어 있습니다.UTF-8 바이트의 비활성화를 특정하기 위해서는 보다 고도의 접근법이 필요합니다.)


온디맨드 부호화 변환 실행:

유틸리티 ★★★★★★★iconv으)로 변환할 수 있습니다.-t ) 및 ( )에서 ( ) ( )로)-f ) 부 )iconv -l에 지원되는 모든 항목을 나타냅니다.

예:

FROM ★★★ISO-8859-1하게 되어 있는 (「」에 하고 있습니다)LC_CTYPE, 「」)UTF-8는 위의 based).

  # Converts to UTF-8; output renders correctly as 'voilà'
sed 's/.*/&/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"

변환에서는, 외국 문자를 적절히 조합할 수 있습니다.

  # Correctly matches 'à' and replaces it with 'ü': -> 'voilü'
sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"

을 ""로 ISO-8859-1후 파이프로 .iconv★★★★★★★★★★★★★★★★★★:

sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')" | iconv -t ISO-8859-1

하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, , 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다,~/.bash_profile ★★★★★★★★★★★★★★★★★」~/.zshrc파일(들)을 클릭합니다.

export LC_CTYPE=C 
export LANG=C

회피책으로는 Perl을 사용하고 있었습니다.

find . -type f -print0 | xargs -0 perl -pi -e 's/was/now/g'

sed 명령어 앞에 iconv 명령어를 파이프로 연결하기만 하면 됩니다.파일 첨부.txt 입력:

iconv -f ISO-8859-1 -t UTF8-MAC 파일txt | sed 's / something / èêùg / g | ....

-f 옵션은 'from' 코드 세트이고 -t 옵션은 'to' 코드 세트 변환입니다.

웹 페이지에는 보통 <charset=iso-8859-1"/>와 같이 소문자가 표시되고 iconv에는 대문자가 사용됩니다.시스템에 명령어 iconv - l을 사용하여 지원되는 아이콘v 코드 집합 목록이 있습니다.

UTF8-MAC은 변환을 위한 최신 OS Mac 코드 세트입니다.

mklement0의 답변은 훌륭하지만 약간의 수정사항이 있습니다.

으로 명시하는 것 .bash를 사용하고 iconv또한 바이트 순서 마크가 없는 UTF-8과 ASCII 사이에는 정당한 혼동이 있을있기 때문에 (Unicode 표준에서는 권장되지 않지만) 바이트 순서 마크를 붙여야 합니다.불행하게도,iconvendianness)를 한 경우 UTF-16BE ★★★★★★★★★★★★★★★★★」UTF-16LE '를.UTF-16 「」를 사용합니다.file --mime-encodingiconv

을 대문자로 .을 대문자로 하기 때문입니다.★★★★★★★★★★★★★★★★★★,iconv 서포트하고 있는 , 「」를 사용하고 있습니다iconv -l을 사용하다)

# Find out MY_FILE's encoding
# We'll convert back to this at the end
FILE_ENCODING="$( file --brief --mime-encoding MY_FILE )"
# Find out bash's encoding, with which we should encode
# MY_FILE so sed doesn't fail with 
# sed: RE error: illegal byte sequence
BASH_ENCODING="$( locale charmap | tr [:lower:] [:upper:] )"
# Convert to UTF-16 (unknown endianness) so iconv ensures
# we have a byte-order mark
iconv -f "$FILE_ENCODING" -t UTF-16 MY_FILE > MY_FILE.utf16_encoding
# Whether we're using UTF-16BE or UTF-16LE
UTF16_ENCODING="$( file --brief --mime-encoding MY_FILE.utf16_encoding )"
# Now we can use MY_FILE.bash_encoding with sed
iconv -f "$UTF16_ENCODING" -t "$BASH_ENCODING" MY_FILE.utf16_encoding > MY_FILE.bash_encoding
# sed!
sed 's/.*/&/' MY_FILE.bash_encoding > MY_FILE_SEDDED.bash_encoding
# now convert MY_FILE_SEDDED.bash_encoding back to its original encoding
iconv -f "$BASH_ENCODING" -t "$FILE_ENCODING" MY_FILE_SEDDED.bash_encoding > MY_FILE_SEDDED
# Now MY_FILE_SEDDED has been processed by sed, and is in the same encoding as MY_FILE

불법 바이트 시퀀스의 위치를 인쇄하는 방법을 아는 사람?아니면 불법 바이트 시퀀스가 뭔지 아는 사람?

$ uname -a
Darwin Adams-iMac 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64

저는 tr을 사용하는 것만으로 위의 답변의 일부를 얻었습니다.

신용 카드 명세서인 .csv 파일을 가지고 있는데 Gnucash로 Import하려고 합니다.저는 스위스에 살고 있기 때문에 취리히와 같은 단어를 다루어야 합니다.Gnucash가 숫자 필드에서 " "를 좋아하지 않는 것으로 의심되면 모두 바꾸기로 결정했습니다.

; ;

와 함께

;;

이하에, 이하를 참조해 주세요.

$ head -3 Auswertungen.csv | tail -1 | sed -e 's/; ;/;;/g'
sed: RE error: illegal byte sequence

빛을 내기 위해 od를 사용했습니다. 이 od -c 출력의 중간 지점에 374가 표시되어 있습니다.

$ head -3 Auswertungen.csv | tail -1 | od -c
0000000    1   6   8   7       9   6   1   9       7   1   2   2   ;   5
0000020    4   6   8       8   7   X   X       X   X   X   X       2   6
0000040    6   0   ;   M   Y       N   A   M   E       I   S   X   ;   1
0000060    4   .   0   2   .   2   0   1   9   ;   9   5   5   2       -
0000100        M   i   t   a   r   b   e   i   t   e   r   r   e   s   t
0000120                Z 374   r   i   c   h                            
0000140    C   H   E   ;   R   e   s   t   a   u   r   a   n   t   s   ,
0000160        B   a   r   s   ;   6   .   2   0   ;   C   H   F   ;    
0000200    ;   C   H   F   ;   6   .   2   0   ;       ;   1   5   .   0
0000220    2   .   2   0   1   9  \n                                    
0000227

그리고 나서 올바른 바이트 코드가 무엇이든 간에 374를 대체하도록 tr을 설득하려고 했습니다.그래서 처음에는 간단한 것을 시도했지만 효과가 없었지만 문제가 되는 바이트가 어디에 있는지 보여주는 부작용이 있었습니다.

$ head -3 Auswertungen.csv | tail -1 | tr . .  ; echo
tr: Illegal byte sequence
1687 9619 7122;5468 87XX XXXX 2660;MY NAME ISX;14.02.2019;9552 - Mitarbeiterrest   Z

374자리에서 철로를 볼 있습니다.

perl을 사용하면 이 문제를 피할 수 있을 것 같습니다.

$ head -3 Auswertungen.csv | tail -1 | perl -pne 's/; ;/;;/g'
1687 9619 7122;5468 87XX XXXX 2660;ADAM NEALIS;14.02.2019;9552 - Mitarbeiterrest   Z?rich       CHE;Restaurants, Bars;6.20;CHF;;CHF;6.20;;15.02.2019

으로는 gnu를 .sed내 목적에 맞게 잘 작동했다.

언급URL : https://stackoverflow.com/questions/19242275/re-error-illegal-byte-sequence-on-mac-os-x

반응형