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


19

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

내가 들어갈 때

grep "^COW" masternospaces.txt

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

하지만 내가 들어갈 때

grep "COW$" masternospaces.txt

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

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

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


3
masternospaces.txt 파일의 출처는 무엇입니까? 유닉스 스타일 LF 대신 Windows 스타일의 라인 터미네이션 (CR-LF)이있을 수 있습니까?
steeldriver

2
확실하지 않지만 목록 단어 또는 목록을 찾고 있습니까?
mikeserv

스틸 드라이버-저것은 저의 첫번째 생각이었습니다. 거기에서 무슨 일이 있었는지, 심지어 어떤 가능성이 있는지 조사하는 방법을 확신하지 못했습니다. 종료 수익은 종료 수익이라고 가정합니다. 이 파일은 몇 가지 소스에서 나온 대규모 개요입니다. 어떤 파일이 원본 파일로 간주되는지 확실하지 않습니다. 그리고 PC와 Mac 컴퓨터 모두에서 최소 3 개의 워드 프로세서를 거치게되었습니다. 어떤 종류의 종료를 사용하는지 확인하는 가장 좋은 방법은 무엇입니까?
DTalvacchio

mikeserv--이 .txt 파일에서 모든 줄은 단어 (또는 단어 사이에 공백이없는 문구이므로 다시 "단어")입니다. 그래서 줄을 찾고 있습니다. . . 각 줄에는 크로스 워드 목적으로 단어를 고려하고있는 것 중 하나만 있습니다.
DTalvacchio

1
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.
user43791

답변:


23

@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하면 어디서 얻을 수 있습니다.

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


그것은 모두 매우 도움이됩니다. 오늘은 시간이 없지만 내일이 모든 내용을 자세히 살펴보고 무엇이 무엇인지 확인할 것입니다. 그 동안 어떤 사람이 좋아하는 유닉스 명령 참조 가이드에 대한 링크가있어서 내가 어떻게 작동하는지 조금 설명 할 수 있다면 고맙겠습니다. 나는 여기저기서 조각을 집어 들었지만 아직 설명을위한 하나의 소스를 찾지 못했습니다. 모두에게 감사하며 희망적으로 성공적인 업데이트로 내일을 체크인 할 것입니다. --D
DTalvacchio

이 게시물이 적어도 닫히지 않은 것이 너무 나쁩니다. 나는 내 인생에서 줄 끝을 맞추는 방법을 알 수 없습니다. 16 진수 덤프를 수행하면 위의 예와 같이 끝나는 멋진 줄을 찾을 수 없습니다. 16 진수 작업에 익숙하지 않으므로 제대로 읽지 못할 수 있습니다. 또한 [[:cntrl:]]@ user43791 제안을 시도했지만 여전히 일치하지 않습니다. 이것은 말이되지 않습니다. 저는 GNU grep 2.20을 사용하고 텍스트 파일에 작성된 nDPI의 출력을 구문 분석합니다
harperville

@harperville 당신이 있다면 cat -v yourfile.ext, 당신은 무엇을 봅 니까?
user43791

흥미 롭거나 예상치 못한 것은 없습니다. 내가 볼 것으로 예상되는 내용. 찾고있는 특정 사항이 있습니까? 여기에 출력을 붙여 넣을 수는 없지만 내용을 볼 수 있습니다. 에 따라 일반 ol ' "ASCII 영어 텍스트" file.
harperville

@harperville 각 줄 끝에 여분의 "^ M"이 없습니까? 16 진수의 처음 몇 줄을 붙여 넣을 수 있습니까?
user43791

1

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

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

따라서 원래 명령의 경우 다음을 사용합니다. grep "COW\'" masternospaces.txt

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

출처 : grep정규식 구문


grep은 시작 ^ (캐럿) 및 끝 \\ (아포스트로피)를
복용

1

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

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

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


-2

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


3
의 확장이 유효하지 않기 때문에 $bash는 단독으로 남겨두고 grep에서 사용합니다. 자신을 참조하십시오 : echo "COW$"- $여전히 거기에있을 것입니다.
Jeff Schaller

-3

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

"COW\$"

1
음 .. 아니야. 는 $그 후 물건이 유효한 쉘 변수 이름이 아니기 때문에, 쉘에 특별한되지 않습니다. 정적 문자열 주위에 작은 따옴표를 사용하는 것이 더 좋지만 여기서는 차이가 없습니다.
Kusalananda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.