접기에 대한 유니코드 안전 대안

접기에 대한 유니코드 안전 대안

나는 fold -w 3한 줄을 3자 길이의 여러 줄로 나누는 데 익숙하지만 GNU 구현을 사용하면 멀티바이트 문자가 있는 텍스트에서는 작동하지 않는 것 같습니다.

위의 목표를 어떻게 달성할 수 있나요 sed?

나는 그것을 알아냈지만 sed -r 's/^(.{0,3})(.*)/\1\n\2/g'이것은 단 한 번의 교체만 수행합니다.

echo "111222333444555666" | sed -r 's/^(.{0,3})(.*)/\1\n\2/g' 
111
222333444555666

다른 예:

echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | sed -r 's/^(.{0,3})(.*)/\1\n\2/g' 
ĄĄĄ
ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ

부패한 fold관행:

echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | fold -w 3                         
Ą�
�Ą
Ą�
�Ą
Ą�

답변1

짧은grep방법:

echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | grep -Eo '.{1,3}'
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄ

3개의 문자 시퀀스만 유지합니다.... | grep -Eo '.{3}'

답변2

문제는 유니코드 문자 세트에 있는 것이 아니라 2바이트 이상을 사용하여 인코딩된 문자(및 1셀 너비가 아닌 문자)에 있다는 점에 유의하십시오.

UTF-8은 U+0080부터 U+10FFFFF까지의 문자가 2바이트 이상으로 인코딩되는 유니코드 인코딩입니다. 유니코드 문자 U+0000 ~ U+007F는 ASCII 문자와 동일하고 UTF-8의 단일 바이트(ASCII 문자와 동일)로 인코딩되므로 여기서는 문제가 되지 않습니다.

유니코드 문자 세트에 대한 다른 인코딩(예: iso8859-1, 단일 바이트이지만 문자 U+0000 ~ U+00FF 또는 GB18030, 멀티바이트로 제한됨)이 있고 다른 멀티바이트 비유니코드 문자도 있습니다. 인코딩을 설정합니다.

이 명령을 사용하여 해당 로케일에서 사용되는 문자 인코딩을 알아볼 수 있습니다 locale charmap.

현재 GNU 구현은 fold단일 바이트 문자만 올바르게 처리합니다. 대부분의 fold다른 시스템에는 이 문제가 없습니다. 많은 경우 디스플레이 너비가 0이거나 두 배인 문자도 처리할 수 있습니다.

2010년부터 busybox 구현은 foldUTF-8을 지원합니다(다른 멀티바이트 문자 매핑은 지원하지 않음).

  • FreeBSD 또는 Solaris의 경우:

      $ echo $'a\u0301bcde' | fold -w3
      ábc
      de
    
  • 비지박스로 접기:

      $ echo $'a\u0301bcde' | busybox fold -w3
      áb
      cde
    
  • GNU 폴딩 사용:

      $ echo $'a\u0301bcde' | fold -w3
      á
      bcd
      e
    

U+0301은 날카로운 조합의 톤입니다. 너비는 널이며 2바이트(0xcc 0x81)의 UTF-8로 인코딩됩니다. 따라서 á( $'a\u0301')는 3바이트로 인코딩된 2개의 문자로 구성된 너비 1의 문자소 클러스터이므로 3가지 다른 동작을 가지며 그 중 가장 정확한 동작은 FreeBSD/Solaris의 동작입니다.

grepPCRE 지원, UTF-8 로케일 및 UTF-8 입력으로 구축된 GNU를 사용하십시오.

grep -Po '\X{1,3}'

각 입력 줄에 o1부터 3까지의 모든 시퀀스(가능한 한 많이)를 출력하면 X문자소 클러스터가 발생하는 경향이 있으며, 이는 토큰을 단일 너비 문자와 결합하는 위의 경우에 대해 더 나은 결과를 제공할 수 있습니다.

2바이트 문자나 1바이트 문자와 결합되지 않은 0문자가 있거나 TAB, CR, BS 등의 제어 문자가 있는 경우에는 도움이 되지 않습니다.

답변3

sed를 사용하세요:

$ echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | sed 's/.../&\n/g'
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄ

또는 보다 일반적인 솔루션(문자 수를 정의하기가 더 쉬움):

sed    's/.\{3\}/&\n/g'             # Using BRE (basic) syntax
sed -E 's/.{3}/&\n/g'               # Using ERE (extended) syntax.

답변4

왜냐하면...

$ echo "ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ" | gawk '{$1=$1} 1' FPAT=".{,3}" OFS="\n"
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄĄ
ĄĄ

관련 정보