Grep를 0으로 제거하지만 0.2는 제거하지 않습니까?


12

내용이 다음과 비슷한 파일이 있습니다.

0
0
0.2
0
0
0
0

하나의 0으로 모든 줄을 제거해야합니다.
사용하려고 생각 grep -v "0"했지만 0.2가 포함 된 줄도 제거합니다. -w옵션을 사용할 수 있다는 것을 알았지 만 작동하지 않는 것 같습니다.

단일 0을 포함하는 모든 줄을 제거하고 모든 줄을 0으로 시작하는 방법은 무엇입니까?



1
@JulienLopez 그것은 그 질문의 속이 아닙니다. 그 질문은 단어를 일치시키는 것에 관한 것이며 여기서 대답 -w하지 않습니다.
Sparhawk

왜이 grep작업 을 사용해야 합니까? 그리고 정확히 하나의 0으로 무엇 을 의미 합니까? 이것은 XY 문제 와 매우 흡사합니다 .
Roland Illig

1
@RolandIllig 그것은 취침 시간 1 시간 전에 있었고 비트 코인 개인 키인지 확인하고 균형을 유지하기 위해 일련의 500,000 문자열 처리를 시작하고 싶었습니다. 다음에 그것을 볼 시간이 있었는데 수천 개의 문자열을 처리했으며 0이 아닌 값을 구문 분석하고 싶었습니다.
Philip Kirkbride

답변:


35
grep -vx 0

보낸 사람 man grep:

-x, --line-regexp
       Select only those matches that exactly match the whole line.
       For a regular expression pattern, this is like parenthesizing
       the pattern and then surrounding it with ^ and $.

-w제 때문에 실패 0에이 0.02는 "워드"로 간주되고, 따라서이 라인이 일치한다. "단어가 아닌"문자가 뒤에 오기 때문입니다. -v예 를 들어 , 없이 원래 명령을 실행하면이 내용을 볼 수 있습니다 grep -w "0".


당신은 또한 사용할 수 있습니다 -F우리는 정규식 패턴을 사용하지 않는 때문에, 그냥 일반 문자열 일치 옵션
글렌 잭맨

@glennjackman 어쩌면 나는 이것을 일찍 읽었지만 지금 그것을 찾을 수없는 것 같습니다. -F놀랍게도 (놀랍게도) 달리는 데는 비슷한 시간이 걸리거나 약간 느리게 나타납니다 (~ 5-10 %). 따라서 이점이 무엇인지 잘 모르겠습니다.
Sparhawk 2012

2
RegEx 엔진이 너무 자주 사용되고 널리 사용되어 매우 효율적인 버전을 구현했지만 "일반 검색"이 30 년 동안 업그레이드되지 않았을 수 있습니다.
Nelson

@Sparhawk : grep아마도 일반적인 사용 사례이기 때문에 메타 문자가없는 정규 표현식 에 특별한 경우가있을 것입니다. fgrep속도가 느리다는 것은 놀라운 일이지만 짧은 패턴을 컴파일하는 동안이 특별한 경우를 인식하는 오버 헤드가 큰 파일을 스캔하는 시간과 비교하여 무시할 수있는 것은 놀라운 일이 아닙니다. (특별히 필요한 경우, 캐릭터 클래스 또는 패턴이있는 패턴과 x.*y
Peter Cordes

그러나 입력이 실제로 많은 짧은 줄 (거대한 문자열이 아님)이기 때문에 지나치게 단순화 된 것일 수 있습니다. 줄 바꿈 grep이외의 \n문자를 줄 구분자로 인식하면 잊어 버립니다 . 그렇지 않은 경우 암시 적 ^이며 $ 여전히 고정 문자열 검색으로 바뀔 수 있습니다 strstr(big_buf, "\n0\n"). (또는 0\n버퍼가 시작될 때) 그러나 우리는 큰 버퍼에서 잠재적으로 멀리 떨어진 첫 번째 일치 항목 만 찾고있는 것이 아니라 효율적으로 필터링하려고합니다. 그러나 어쨌든 이론적으로는 각 줄의 시작 부분에 2 바이트 memcmp 일뿐이므로 fgrep 및 grep이 모두 볼 수 있기를 바랍니다.
Peter Cordes 2019

28

grep로 :

grep -v "^0$" file

^줄의 시작을 의미하고 줄의 $끝을 의미합니다.


2
이것은 사용자가 요청한 것입니다. 1 "0"만 포함 된 행은 피하십시오.
Olivier Dulac

1
나는 큰 따옴표 안에 리터럴 달러 기호를 넣지 않을 것입니다.
user541686

@mehrdad는 보통 마지막 문자이거나 다음 문자가 아니기 때문에 정규 표현식에 큰 문제가 아닙니다.[a-Z0-9]
Sampo Sarrala-codidact.org

14

이것을 위해 사용할 grep 있지만 (다른 답변이 분명히 보여 주듯이) 한 발짝 물러서 실제로 원하는 것을 생각해 봅시다.

  • 숫자가 포함 된 파일이 있습니다
  • 숫자 값을 기준으로 필터링을 수행하려고 합니다 .

정규식은 문자 시퀀스 데이터를 해석합니다. 숫자에 대해서는 알지 못하고 개별 자릿수 (및 정기적 인 조합)에 대해서만 알 수 있습니다. 특별한 경우이 제한에 대한 간단한 해킹이 있지만 궁극적으로 요구 사항이 일치하지 않습니다.

grep여기 에 사용해야 할 이유가 충분하지 않은 경우 (예 : 측정 한 결과 훨씬 더 효율적이고 효율성이 결정적인 경우) 다른 도구를 사용하는 것이 좋습니다.

awk예를 들어 숫자 비교를 기준으로 필터링 할 수 있습니다 (예 :

awk '$1 == 0' your_file

또한 0보다 큰 숫자를 포함하는 모든 줄을 얻으려면 :

awk '$1 > 0' your_file

나는 정규 표현식을 좋아합니다. 훌륭한 도구입니다. 그러나 이것이 유일한 도구 는 아닙니다 . 말 그대로, 당신이 가진 grep모든 것이 일반 언어처럼 보입니다.


3
나는 awk가 더 우아 할 수 있다는 것에 진심으로 동의하지만 ... 또한 사용자가 기대하는 것보다 조금 더 일치 할 것입니다 (모든 숫자 값은 0으로 평가됨). 즉, printf '0\n1\n-1\na\nb\n0\n0 also\n0.0\n-0.0\n0*0\n' | awk '($1 == 0)'일치하는 것 0, 0.0그리고 -0.0... 그리고도 0 also! "0"만이 아닙니다. (때로는 필요하지만 때로는 그렇지 않습니다). 사용자가 "0"만 원하는 경우 : awk '/^0$/' (또는 grep '^0$'). 또한 편집해야합니다 : 사용자 !는 테스트를 무효화하기 위해 추가해야 하므로 숨기기 0및 기타 0을 표시합니다. 즉 :awk '!( $0 == 0)'
Olivier Dulac

1
@Olivier, 또는 문자열 값을 확인하십시오$1 == "0"
글렌 잭맨

1
@OlivierDulac 나는 이것이 평등뿐만 아니라 임의의 숫자 비교임을 강조하기 위해 (또는 동등하게 ) >대신 명시 적으로 사용했습니다 . 다른 의견에 관해서는, 이것은 전적으로 사실이지만 우리는 본질적으로 문자열 비교 영역과 작업 을 사용하는 기존 솔루션으로 돌아 왔습니다 ( 물론 작동합니다). !=! (… == …)grepawk
Konrad Rudolph

@KonradRudolph fair points :)
Olivier Dulac

1
@glennjackman : 참으로 멋진 트릭입니다. 그러나 영업 이익은 오히려 시험 할 것$0=="0"
올리비에 Dulac

5

grep의는 -w그것 (문자, 숫자 또는 밑줄을 제외하고 아무것도) 원래의 단어와 비 단어 구성에 문자열을 분할하는 방식으로 뒤얽힌 조금이다. 그것은 이미 유효한 단어 구성 요소 0를 만났기 때문에 그 0.02줄을 제거하기 위해 부정 논리를 주장했다.

sed이 문맥에서 사용 하는 것은 일치하는 전체 단어를 제거하기가 약간 쉽습니다.

sed '/^0$/d' file

3

삭제하려는 행에 다음 행만 포함 된 경우 다음 명령을 실행하여 해당 행을 선택할 수 있습니다.0

grep -v "^0$"

이것은 단지의 발생 인쇄 할 수 0있는 줄 끝에행의 시작 부분에 같은 시간에 있습니다. -v그런 다음 옵션 이 선택을 반전시킵니다.


1
이 답변은 Arkadiusz Drabczyk와 거의 동일하지만을 잊어 버렸 -v으므로 작동하지 않습니다.
Sparhawk

네가 옳아. 그가 답변을 게시하는 동안 입력하고 있었으므로 답변이 이미 제공되지 않았습니다. 나는 -v옵션으로 그 부분을 잘못 읽었습니다 . 감사합니다!
majesticLSD

0
  • \ b-단어 테두리

grep -v "\b0\b"

  • 줄의 시작, 패턴 및 줄의 끝과 일치

grep -v "^0$"

  • 또는 @Sparhawk이 제안한대로 -vx lineregexp

-w 는 작동하지만 점 문자는 단어 구분 기호이므로 0.2 는 두 단어입니다.


grep -v "\b0\b"여기서 실제로 작동하지 않습니다. 어떤 버전의 grep을 사용하십니까?
Arkadiusz Drabczyk

작동 grep (BSD grep) 2.5.1-FreeBSD맥 OS와 grep (GNU grep) 2.16우분투
야쿱 Jindra

1
GNU 사용을 정규식 \<\>같은 단어 경계로,하지만 같은 영향을 미칠 것입니다-w
글렌 잭맨

0

PCRE를 사용할 수 있다고 가정하면 다양성을위한 또 다른 대답 grep

grep -Pv "^0(?!\.)"

이러한 수행은 네거티브 룩어 로 시작하는 라인과 일치하도록 0하고 되지 않는 점을 하였다. 그런 다음 -v일치하지 않는 줄을 버립니다. 여기 에서 실제로 볼 수 있습니다


1
또한 0123OP 와 같은
행도

0

단일 0이 아닌 모든 라인에 마침표가 있다고 가정

grep '\.' file

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.