[unix] 줄 앞의 앵커가 앵커인데도 줄 끝 $ 앵커가 grep 명령과 작동하지 않는 이유는 무엇입니까?

유닉스에 매우 익숙하지만 프로그래밍에는 새로운 것이 아니다. MacBook에서 터미널 사용. 크로스 워드 생성을 위해 단어 목록을 관리하고 검색하기 위해 Grep 명령과 그 변형을 사용하려고합니다. 매우 간단 해 보이지만 간단한 경우라고 생각한 것에 대해 일찍 끊어졌습니다.

내가 들어갈 때

grep "^COW" masternospaces.txt

COW로 시작하는 모든 단어 목록 : 내가 원하는 것을 얻습니다.

하지만 내가 들어갈 때

grep "COW$" masternospaces.txt

나는 COW로 끝나는 단어 목록을 얻을 것으로 예상합니다 (많은 단어가 있습니다).

파일은 일반 텍스트 파일이며 모든 줄에는 모든 대문자로 된 단어 (또는 공백이없는 단어 문구) 만 있습니다.

여기서 무슨 일이 일어날 지 아십니까?



답변

@steeldriver가 언급했듯이 문제는 예상과 다른 라인 엔딩 스타일로 인해 발생할 수 있습니다 grep.

줄 끝을 확인하려면

hexdump줄 끝의 형식을 정확하게 확인 하는 데 사용할 수 있습니다 . 내가 좋아하는 형식을 사용하는 것이 좋습니다.

hexdump -e '"%08_ad (0x%08_ax)    "8/1 "%02x ""   "8/1 "%02x "' -e '"    "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt

출력으로 줄 끝을 확인하십시오 : 0a-> LF, 0d-> CR. 매우 빠른 예는 다음과 같습니다.

$ hexdump -e '"%08_ad (0x%08_ax)    "8/1 "%02x ""   "8/1 "%02x "' -e '"    "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
00000000 (0x00000000)    4e 6f 20 43 4f 57 20 65   6e 64 69 6e 67 0d 0a 45    No COW e|nding..E
00000016 (0x00000010)    6e 64 69 6e 67 20 69 6e   20 43 4f 57 0d 0a          nding in| COW..

행 끝은 dos 형식 0d 0a입니다.

줄 끝을 변경하려면

다양한 도구를 사용하여 줄 끝을 변경하는 다양한 방법에 대해서는 여기 또는 여기 를 볼 수 있지만 한 번에 vi / vim을 사용할 수 있습니다.

vim masternospaces.txt
:set fileformat=unix
:wq

아무것도 바꾸지 않고 grep하려면

grep줄 끝과 상관없이 일치 시키 려면 항상 다음과 같이 줄 끝을 지정할 수 있습니다.

grep 'COW[[:cntrl:]]*$' masternospaces.txt

빈 줄이 표시되면 다음 -v옵션을 사용하여 실제로 일치하는 것을 확인할 수 있습니다 cat.

grep 'COW[[:cntrl:]]*$' masternospaces.txt | cat -v

내가 개인적으로 좋아하는 것

다음을 사용하여 출력을 grep하고 표준화 할 수도 있습니다 sed.

sed -n '/COW^M*$/{;s/^M//g;p;};' masternospaces.txt

키보드 ^M로 입력 Ctrl-V Ctrl-M하면 어디서 얻을 수 있습니다.

도움이 되었기를 바랍니다!


답변

grep과 함께 ‘표준’RegEx 구문을 사용할 수 있지만 ( @ user43791의 답변 에서처럼 ) grep에는 입력 경계를 나타내는 다른 식별자도 있습니다.

전체 줄의 시작과 끝에 대한 매처는 \`(대신 ^) 대신 () 대신 ( )와 \'(아포스트로피 $)입니다.

따라서 원래 명령의 경우 다음을 사용합니다.

grep "COW\'" masternospaces.txt

사이드 노트 : 그것은주의하는 것도 중요 ?하고 +당신이 그 (것)들을 사용하여 탈출하지 않는 한 그대로 처리됩니다 \?그리고 \+그들에게 그들의 정규식 스타일 선택기 대응을 할 수 있습니다.

출처 : grep정규식 구문


답변

\rgrep 이전 을 제거하는 다른 방법 :

... | dos2unix | egrep 'COW$' | ...

나는 [[:cntrl:]]오랫동안 같은 것들을 기억하지 못하기 때문에 그것이 매우 분명하다는 것을 좋아 합니다.


답변

bash가 grep에 대한 매개 변수를 설정할 때 “COW $”는 “$”를 “”로 취급하는 “COW”로 해석되었으며, $는 이탈 심볼입니다. $로 대화하지 않은 경우 bash 셸에서 빈 문자열로 해석되므로 grep ‘COW $’masternospaces.txt를 대신 사용해야합니다.


답변

BSD grep에서는 “$”를 이스케이프하고 문자열을 큰 따옴표로 묶어야합니다.

"COW\$"


답변