유니코드 코드 포인트 16A0으로 표시되는 텍스트 파일에 유니코드 문자 ᚠ가 있습니다(텍스트 파일은 utf-8로 인코딩(?)됩니다).
이렇게 하면 grep '\u16A0' test.txt
결과가 나오지 않습니다. 이 캐릭터를 어떻게 찾을 수 있나요?
답변1
당신은 그것을 사용할 수 있습니다ANSI-C 인용문ANSI C 표준에 지정된 백슬래시 이스케이프 문자를 대체하기 위해 셸에서 제공됩니다. 이는 grep
Bash 및 Zsh와 같은 셸의 명령 뿐만 아니라 모든 명령에서 작동합니다 .
grep $'\u16A0'
좀 더 복잡한 예를 보려면 다음을 참조하세요.이 관련 질문그리고 그 대답.
답변2
당신이 사용할 수있는우그레프유니코드 코드 포인트 U+16A0과 일치하도록 grep을 직접 대체합니다.
ugrep '\x{16A0}' test.txt
grep과 동일한 옵션을 사용하지만 다음과 같은 더 많은 기능을 제공합니다.
ugrep은 UTF-8/16/32 입력 및 기타 형식을 검색합니다.. 옵션 -Q를 사용하면 ISO-8859-1~16, EBCDIC, 코드 페이지 437, 850, 858, 1250~1258, MacRoman 및 KIO8과 같은 다양한 파일 형식을 검색할 수 있습니다.
ugrep은 유니코드 패턴과 일치합니다.기본적으로(-U 옵션으로 비활성화됨) 정규식 패턴 구문은 POSIX ERE 표준을 따르며 PCRE와 유사한 구문으로 확장됩니다. -P 옵션은 Perl 및 유니코드 패턴 일치에도 사용할 수 있습니다.
바라보다GitHub의 ugrep더 알아보기.
답변3
사용행복하다(이전 Perl_6)
입력 예:
https://www.cogsci.ed.ac.uk/~richard/unicode-sample-3-2.html
문자 일치, 줄 인쇄:
~$ raku -ne '.put if m/ \x[16A0] /;' file
ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ ᚪ ᚫ ᚬ ᚭ ᚮ ᚯ ᚰ ᚱ ᚲ ᚳ ᚴ ᚵ ᚶ ᚷ ᚸ ᚹ ᚺ ᚻ ᚼ ᚽ ᚾ ᚿ ᛀ ᛁ ᛂ ᛃ ᛄ ᛅ ᛆ ᛇ ᛈ ᛉ ᛊ ᛋ ᛌ ᛍ ᛎ ᛏ ᛐ ᛑ ᛒ ᛓ ᛔ ᛕ ᛖ ᛗ ᛘ ᛙ ᛚ ᛛ ᛜ ᛝ ᛞ ᛟ ᛠ ᛡ ᛢ ᛣ ᛤ ᛥ ᛦ ᛧ ᛨ ᛩ ᛪ ᛫ ᛬ ᛭ ᛮ ᛯ ᛰ
#OR:
~$ raku -e 'lines.grep(/ \x[16A0] /).put;' file
ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ ᚪ ᚫ ᚬ ᚭ ᚮ ᚯ ᚰ ᚱ ᚲ ᚳ ᚴ ᚵ ᚶ ᚷ ᚸ ᚹ ᚺ ᚻ ᚼ ᚽ ᚾ ᚿ ᛀ ᛁ ᛂ ᛃ ᛄ ᛅ ᛆ ᛇ ᛈ ᛉ ᛊ ᛋ ᛌ ᛍ ᛎ ᛏ ᛐ ᛑ ᛒ ᛓ ᛔ ᛕ ᛖ ᛗ ᛘ ᛙ ᛚ ᛛ ᛜ ᛝ ᛞ ᛟ ᛠ ᛡ ᛢ ᛣ ᛤ ᛥ ᛦ ᛧ ᛨ ᛩ ᛪ ᛫ ᛬ ᛭ ᛮ ᛯ ᛰ
문자 일치, 인쇄(공백으로 구분) "단어":
~$ raku -ne 'for .words() { .put if m/ \x[16A0] / };' file
ᚠ
#OR:
~$ raku -e 'words.grep(/ \x[16A0] /).put;' file
ᚠ
문자 일치, (정확한) 일치 인쇄:
~$ raku -e 'given slurp() { put m:g/ \x[16A0] / };' file
ᚠ
#OR:
~$ raku -e 'slurp.match(:global,/ \x[16A0] /).put;' file
ᚠ
문자를 일치시키고 일치하는 수를 세어 인쇄합니다.
~$ raku -e 'given slurp() { put m:g/ \x[16A0] /.Int };' file
1
#OR:
~$ raku -e 'slurp.match(:global,/ \x[16A0] /).elems.put;' file
1
노트:
Raku에서는 유니코드 이름을 쉽게 일치시킬 수 있습니다
\c[RUNIC LETTER FEHU FEOH FE F]
. 예를 들어 위의 일치와 동일한 결과를 제공합니다\x[16A0]
.Raku에서는 예를 들어 유니코드 문자를 쉽게 일치시킬 수 있으며, 이는
ᚠ
일치 이상과 동일한 결과를 제공합니다.\x[16A0]
\c[RUNIC LETTER FEHU FEOH FE F]
Raku에서는 유니코드 변수(및 유니코드 연산자)를 사용할 수 있습니다. 그래서 이것은 작동합니다 :
~$ raku -e 'my $ᚠ = slurp.match(/ \x[16A0] /); say $ᚠ.Str.raku;' file
"ᚠ"
https://docs.raku.org/언어/regexes#Unicode_properties
https://docs.raku.org/언어/unicode
https://docs.raku.org
https://raku.org
답변4
을 사용 perl
하거나 pcre2grep
적어도 pcregrep
PCRE 또는 PCRE2 구현을 사용하면 문자를 값과 일치시키는 데 사용할 수 있습니다(또는 값 <= 0xff에 대해서만).grep
\x{16A0}
0x16A0
\xe9
값이 유니코드 코드 포인트가 되려면 입력이 UTF-8에서 디코딩되어야 한다고 알려야 합니다. PCRE/PCRE2에서는 (*UTF)
패턴의 시작 부분에서 이를 사용하여 수행됩니다 (주로 PCRE_UTF
정규식 엔진에 전달하는 것과 동일). 그러나 최신 버전의 GNU는 grep
최소한 UTF-8을 사용하는 로케일에서 호출될 때 자동으로 이 작업을 수행합니다. 문자 맵 이 작업입니다. pcregrep
및 의 경우 pcre2grep
옵션을 사용하여 이 기능을 활성화할 수도 있습니다 -u
( 참조 -U
) pcre2grep
.
에서는 환경 변수 의 (큰 문자) 옵션을 perl
통해 이루어집니다 . 단독으로 사용하는 경우 약어는 로케일 이 GNU와 같이 UTF-8을 사용하는 경우 입력/출력을 UTF-8로 다시 인코딩하기 위해 디코딩/재인코딩 되거나 이를 무조건 수행하거나 모듈 등을 사용하여 모든 인코딩에서 명시적으로 디코딩합니다 .-C
PERL_UNICODE
-C
-CSDL
grep
-CSD
Encode
PCRE2(GNU 또는 최신 버전에서 사용 perl
)에서는 유니코드 이름이 .pcre2grep
grep
\N{U+16A0}
perl
\N{RUNIC LETTER FEHU FEOH FE F}
그래서:
perl -C -ne 'print if /\x{16A0}/'
perl -C -ne 'print if /\N{U+16A0}/'
perl -C -ne 'print if /\N{RUNIC LETTER FEHU FEOH FE F}/'
PERL_UNICODE=SD perl -ne 'print if /\x{16A0}/'
pcregrep -u '\x{16A0}'
pcregrep '(*UTF)\x{16A0}'
pcre2grep -u '\x{16A0}'
pcre2grep '(*UTF)\x{16A0}'
pcre2grep -U '\x{16A0}'
pcre2grep -u '\N{U+16A0}'
grep -P '\x{16A0}'
UTF-8로 인코딩되지 않은 입력에서 유니코드 값을 기반으로 문자를 일치시키려면 이러한 문자는 UTF-8에서만 작동하므로 작동하지 않습니다. 단일 바이트 문자 집합에서는 \xHH
값(유니코드의 코드 포인트가 아닌 해당 문자 집합의 코드 포인트)으로 작동합니다.
예를 들어, en_GB.iso885915
로케일에서 유로 기호(U+20AC)는 0xA4에 있습니다.
$ LC_ALL=en_GB.iso885915 luit
$ locale charmap
ISO-8859-15
$ printf %s € | od -An -vtx1
a4
$ echo € | grep -P '\x{20ac}'
grep: character code point value in \x{} or \o{} is too large
$ echo € | grep -P '\N{U+20ac}'
grep: \N{U+dddd} is supported only in Unicode (UTF) mode
$ echo € | grep -P '(*UTF)\N{U+20ac}'
$ echo € | grep -P '\xA4'
€
따라서 옵션은 텍스트를 UTF-8로 변환하는 것입니다.
$ echo € | iconv -t utf-8 | LC_ALL=C.UTF-8 grep -P '\x{20ac}' | iconv -f utf-8
€
또는 대신 perl
use를 사용하는 경우 UTF-8 대신 로케일의 문자 집합에 따라 입력/출력을 디코딩/인코딩하도록 지시합니다.-Mopen=locale
-C
$ echo € | perl -Mopen=locale -ne 'print if /\N{U+20ac}/'
€
또는 디코딩을 수행하지 않고 로캘에 있는 문자의 바이트 값과 일치합니다.
예를 들어 GNU, zsh 또는 최신 버전의 bash를 사용하면 다음과 같습니다 printf
.
$ locale charmap
ISO-8859-15
$ printf '\u20ac' | od -An -vtx1
a4
$ echo € | grep -F -- "$(printf '\u20ac')"
€
zsh에서는 당시 현재 로케일의 문자 인코딩으로 확장되는 which를 사용할 수도 있습니다 $'\u20ac'
(해당 로케일에 해당 문자가 없으면 오류를 보고합니다).
$ echo € | grep -F -- $'\u20ac'
€
$'\uHHHH'
ksh93, bash, mksh 및 일부 ash 기반 쉘을 포함하여 여러 다른 쉘이 이를 zsh 에서 복사했지만 일부 불행한 차이점이 있습니다. ksh에서는 로케일에 관계없이 UTF-8로 확장되는 반면 bash의 경우 코드가 실행될 때의 로케일이 아닌 코드를 읽을 때의 로케일입니다. 예를 들어 다음과 같습니다 bash
.
LC_CTYPE=C.UTF-8
{
LC_CTYPE=en_GB.iso885915
printf '\xA4\n' | grep -F -- $'\u20ac'
}
또는:
LC_CTYPE=C.UTF-8
euro() {
grep -F -- $'\u20ac'
}
LC_CTYPE=en_GB.iso885915
printf '\xa4\n' | euro
두 경우 모두 쉘이 구문 분석될 때 아직 실행되지 않았기 $'\u20ac'
때문에 UTF-8 인코딩으로 확장되므로 작동하지 않습니다 .LC_CTYPE=en_GB.iso885915
$'\u20ac'