Linux에서 "wc -c"및 "wc -m"명령


24

텍스트 파일이 있는데 그 내용은 다음과 같습니다.

i k k

wc -m이 파일에서 문자 수를 계산 하는 데 사용 하면 결과는 7 입니다.

질문 1 : 그러나 왜 " end-of-line "문자를 포함 한다고 가정 하면 " 6 "을 얻지 않아야 합니까?

질문 2 : 정확히 어떻게 wc -m작동합니까?

질문 3 : wc -c(바이트 수를 계산하기 위해)를 사용할 때 와 같은 결과를 wc -m얻으므로 두 가지 옵션이 무엇입니까? 그들은 정확히 같은 일을합니까? 그렇지 않은 경우 차이점 wc -c은 무엇 이며 어떻게 작동합니까?



1
파일이 CRLF 줄로 끝나는 Windows에서 온 경우 7을받을 수도 있습니다.
Chris H

답변:


36

실제로 6 자만 있어야합니다. 달리기

cat -A filename

파일의 비 인쇄 문자를 보려면 여분의 것이 있어야합니다. 내가 너처럼 파일을 만들면

i k k$

공간을 두었습니까? 7을 만들 i k k $거나 줄 바꿈이있을 수 있습니다.

i k k$
$

또한 7입니다

당신이 말한대로

wc -m

문자를 세고

wc -c

바이트를 계산합니다. 모든 문자가 ASCII 문자 세트의 일부인 경우 문자 당 1 바이트 만 존재하므로 두 명령에서 같은 수를 얻게됩니다.

ASCII 문자가 아닌 파일을 사용해보십시오.

$ echo ك > testfile
$ wc -m testfile
2 testfile
$ wc -c testfile
3 testfile

아하! 문자보다 많은 바이트.


3
" cat -A "명령을 사용 했는데 마침내 " end-of-line "문자 ( $ ) 앞에 공백이 하나 있다는 것을 알았습니다 . 그렇기 때문에 6 대신 7을 얻었습니다. 감사합니다. " cat -A "가 많은 도움을주었습니다.
SWIIWII

2
@SWIIWII 그래, 아마 내 생각에 아마 그것이 될 것이라고 생각 한대로 내 대답에 추가했습니다 :)
Zanna

1
줄 바꿈 문자도 계산되었습니다. 비록 보이지 않는 경우에도 여전히 문자이며 파일에서 데이터 청크로 계산됩니다. 그건 그렇고 고양이 -A를 잘 사용합니다. 한
번도

@ Serg 네, 그리고 cat -A그것을 보여줄 것입니다. 나는 내 대답에 감사를 더했다 :)
Zanna

@SWIIWII는 `likethis`읽을 수 있도록 코드를 백틱 에 넣 습니다. 굵게 표시하지 마십시오
phuclv

2
$ locale charmap
UTF-8

현재 환경에서 문자 세트는 UTF-8입니다. 즉, 문자는 문자 당 1 ~ 4 바이트로 인코딩됩니다 (UTF-8의 원래 정의는 최대 0x7fffffff를 허용하므로 대부분의 도구는 UTF-를 인식합니다) 최대 6 바이트의 8 바이트 시퀀스).

해당 문자 세트에서 유니 코드의 모든 문자를 사용할 수 있으며, a a는 바이트 값 65, a 는 3 바이트 228 185 149 및 é2 바이트 시퀀스 195 169로 코딩됩니다.

$ printf 乕 | wc -mc
  1       3
$ printf a | wc -mc
  1       1

지금:

$ export fr_FR.iso885915@euro
$ locale charmap
ISO-8859-15

문자 세트가 이제 ISO-8859-15 인 환경을 수정했습니다 (언어, 통화 기호, 날짜 형식과 같은 다른 것들도 수정되었습니다. 지역 설정 모음은 로케일 이라고합니다 ). 캐릭터 렌더링을 새로운 로케일에 적용하려면 해당 환경에서 새로운 터미널 에뮬레이터를 시작해야합니다.

ISO-8859-15는 단일 바이트 문자 세트이므로 256 자 (실제로 적용되는 것보다 훨씬 적음) 만 있습니다. 이 특정 문자 집합은 대부분의 언어와 유로 기호를 포함하므로 서유럽 언어에 사용됩니다.

그것은이 aUTF-8 또는 ASCII에서, 그것은 또한이 같은 바이트 값 65 문자 é문자 (같은 일반적으로 예를 들어 프랑스어 나 스페인어로 사용)하지만 바이트 값 (233)와, 그것은乕문자를하지 않습니다.

해당 환경에서, wc -c그리고 wc -m항상 같은 결과를 줄 것이다.

대부분의 최신 유닉스 계열 시스템과 마찬가지로 우분투에서는 전체 유니 코드 범위를 포괄하는 유일한 지원 문자 세트 (및 인코딩)이므로 기본값은 UTF-8입니다.

다른 멀티 바이트 문자 인코딩이 존재하지만 Ubuntu에서 잘 지원되지 않으며 그와 함께 로케일을 생성하려면 후프를 거쳐야합니다. 그렇다면 많은 것들이 그렇지 않다는 것을 알게 될 것입니다 올바르게 작동.

따라서 우분투에서 문자 세트는 단일 바이트 또는 UTF-8입니다.

이제 몇 가지 참고 사항이 있습니다.

UTF-8에서 모든 바이트 시퀀스가 ​​유효한 문자를 형성하는 것은 아닙니다. 예를 들어, ASCII가 아닌 모든 UTF-8 문자는 모두 8 번째 비트 세트를 갖는 바이트로 구성되지만 첫 번째 문자 만 7 번째 비트 세트를 갖습니다.

8 번째 비트 세트가있는 일련의 바이트가 있고 그 중 7 번째 비트 세트가없는 바이트는 문자로 변환 될 수 없습니다. 그리고 소프트웨어가 무엇을해야할지 모르기 때문에 문제와 불일치가 발생하기 시작한 때입니다. 예를 들어 :

$ printf '\200\200\200' | wc -mc
      0       3
$ printf '\200\200\200' | grep -q . || echo no
no

wc그리고 grep거기에 문자가 없습니다 :

$ x=$'\200\200\200' bash -c 'echo "${#x}"'
3

bash finds 3. 일련의 바이트를 문자에 맵핑 할 수 없으면 각 바이트를 문자로 간주합니다.

유니 코드에는 문자로 유효하지 않은 코드 포인트와 문자가 아닌 일부 코드 포인트가 있으며 도구에 따라 UTF-8 인코딩이 문자로 간주되거나 고려되지 않을 수 있으므로 훨씬 더 복잡해질 수 있습니다.

고려해야 할 또 다른 사항은 캐릭터와 그래 핀의 차이점과 렌더링 방법입니다.

$ printf 'e\u301\u20dd\n'
é⃝
$ printf 'e\u301\u20dd' | wc -mc
      3       6

여기에 3 개의 문자를 하나로 결합하여 3 개의 문자를 6 개의 바이트로 렌더링하여 3 개의 문자를 결합했습니다 (한 개의 기본 문자, 급성 악센트 및 결합하는 원).

wcUbuntu에서 찾은 GNU 구현 -L에는 입력에서 가장 넓은 선의 표시 너비를 알려주 는 스위치가 있습니다.

$ printf 'e\u301\u20dd\n' | wc -L
1

또한 일부 문자는 위 의 문자 와 같이 너비 계산에서 2 을 차지한다는 것을 알 수 있습니다 .

$ echo 乕 | wc -L
2

결론적으로, 한마디로 바이트, 문자 및 그래프가 반드시 같을 필요는 없습니다.


1

의 차이 wc -c와는 wc -m반면 후자의 카운트 문자, 멀티 바이트 문자 (예를 들어, UTF8), 전 카운트 바이트 로케일에 그입니다. 다음 파일을 고려하십시오.

$ hexdump -C dummy.txt 
00000000  78 79 cf 80 0a                                    |xy...|

(UTF8을 사용하지 않는 사람들에게는 문자 'x', 'y'및 'π'다음에 줄 바꿈이 있습니다). 길이는 5 바이트입니다.

$ wc -c dummy.txt 
5 dummy.txt

네 글자 만

$ wc -m dummy.txt 
4 dummy.txt

또는 모든 문자에 4 바이트가있는 UTF-32도 고려하십시오.
Jörg W Mittag
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.