보통 우리가 일반적으로 파일의 줄 수를 세고 싶을 때는 다음과 같이 합니다.


# wc -l <Filename>


혹은


# cat <Filename> | wc -l



보통은 크게 틀릴 일이 없지요.


다만 wc -l 이 하는 역할이 무엇이냐 를 잘 생각해야 합니다.


wc -l 은 "줄 수" 를 세는 것이 아니라 "줄바꿈 문자의 갯수" 를 셉니다.


이를테면 이런 경우가 발생할 수 있습니다.


[root@cenos6-anaconda35 tmp]# echo -ne  "1\n2\n3" > a.txt

[root@cenos6-anaconda35 tmp]# cat ./a.txt

1

2

3[root@cenos6-anaconda35 tmp]# wc -l ./a.txt

2 ./a.txt

[root@cenos6-anaconda35 tmp]# cat ./a.txt | wc -l

2

[root@cenos6-anaconda35 tmp]#


뭔가 좀 그렇죠? 실제 파일은 3개의 라인으로 이루어져 있지만 줄바꿈 문자는 2개밖에 없으니 2를 출력합니다.


이 경우 다음과 같이 파일을 세면 좀 더 정확하게 셀 수 있습니다.


[root@cenos6-anaconda35 tmp]# cat ./a.txt | grep -c ""

3

[root@cenos6-anaconda35 tmp]# grep -c "" ./a.txt

3

[root@cenos6-anaconda35 tmp]# 



grep -c 를 이용해서 조건과 일치하는 줄의 갯수를 셉니다. 그런데 이 문제는 다소 트릭 같습니다.


왜냐하면 원래 이렇게 작동하는 방식이 아니어야 할 것 같거든요.


시스템이 "" 를 어떻게 처리하는지 확인해 봅시다.


[root@cenos6-anaconda35 tmp]# echo -ne "\n" | hexdump -c

0000000  \n

0000001

[root@cenos6-anaconda35 tmp]# echo "" | hexdump -c

0000000  \n

0000001 


실제로 "" 는 일반적인 Line Feed 문자와 동일하게 취급됩니다.


그런데 grep 에서는 없어도 잡히는 듯 합니다. 그래서 이건 일종의 트릭이죠. 아마 grep 이 파일을 다루는 방식이 일반적인 생각과 조금 다른 모양입니다. (이 문제는 grep 과 관련된 몇가지 테스트를 해보다 보면 느끼게 됩니다.)

- grep 의 작동방식은 https://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html 참조

- grep 이 Line Feed 를 제대로 다루지 않는 문제를 좀 더 상세히 확인할 수 있는 grep의 Posix Spec : http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html

 - 해당 스펙에 따르면 "" 를 "개행문자" 로 처리하면 안되기때문에 일종의 공백문자 정도로 다루는 식으로 작동하는게 아닌가 하는 의심이 있습니다. 정확한 소스를 확인한 것은 아니니 주의.



아마 이 문제를 좀 더 시스템적으로 올바르게(System Correctness?) 표현하여 명시적으로 다루고자 한다면 이런 식으로 해야 할 것입니다.


[root@cenos6-anaconda35 tmp]# grep -c "^" ./a.txt

3


+ Recent posts