특정 패턴을 기반으로 선을 잡는 방법은 무엇입니까?


8

다음 두 줄을 포함하는 파일이 있다고 가정 해 봅시다.

2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
2014-05-05      09:12:17    /aa/bbbb/cccccc?dddddddd    16767 

패턴 /aa/bbbb/cccccc만 포함하는 줄을 가져와야합니다 ?dddddddd. 추가 문자가 포함 된 두 번째 줄은 필요하지 않습니다 . 내가 시도했을 때

grep '/aa/bbbb/cccccc' file

그런 다음 두 줄을 모두 선택합니다. 나는 전체 라인이 필요하므로 grep -o해결책이 될 수 없습니다.

검색 패턴에 따라 첫 번째 행만 선택되도록 grep 을 사용하여 가능한 솔루션은 무엇입니까 ?

답변:


7

-P( Perl-regexp ) 매개 변수 를 사용하는 아래 grep 명령을 사용해보십시오 .

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S)이 부정적인 룩백은 문자열을 선행하는 문자가 /aa/bbbb/cccccc공백이 아닌 문자가 될 것이라고 주장합니다 .

  • (?!\S) 부정적 예측은 일치하는 문자가 공백이 아닌 문자가 될 것이라고 주장합니다.

또 다른 grep

 grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file

파이썬을 통해

script.py

#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
    for line in f:
        for i in line.split():
            if i == "/aa/bbbb/cccccc":
                print(line, end='')

위의 코드를 파일에 저장하고 이름을로 지정하십시오 script.py. 그런 다음 위의 스크립트를

python3 script.py /path/to/the/file/you/want/to/work/with

고마워요 Btw 이것은 perl 정규 표현식 대신 정규 / 확장 정규 표현식을 사용하여 수행 할 수 있습니까?
heemayl

1
terdon 게시처럼 당신은 간단 하 게grep '/aa/bbbb/cccccc ' file
Avinash Raj

그러나 위의 /aa/bbbb/cccccc문자열 만 문자열을 인쇄하지 않습니다 .
Avinash Raj

당신도 그와 일치시킬 수 있습니다grep -E '/aa/bbbb/cccccc(\s+|$)' file
terdon

예, 이렇게grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Avinash Raj

10

가장 간단한 방법은 패턴 뒤에 공백을 추가하는 것입니다.

$ grep '/aa/bbbb/cccccc ' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

또는 모든 종류의 공백과 일치 시키려면

$ grep  '/aa/bbbb/cccccc[[:space:]]' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

또는

$ grep -P '/aa/bbbb/cccccc\s+' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

또는 긍정적 인 예견으로 :

$ grep -P '/aa/bbbb/cccccc(?=\s)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

또는 부정적인 예측으로 :

$ grep -P '/aa/bbbb/cccccc(?!\S)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

또는 일치를 되돌릴 수 있습니다.

$ grep  -v 'c?' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

또는 패턴 만 포함하는 행과 일치 시키려면 (공백 공백 없음) :

grep -P '/aa/bbbb/cccccc(\s+|$)' file 
grep -E '/aa/bbbb/cccccc(\s+|$)' file 

또는 작은 스크립트를 사용할 수 있습니다.

  • awk에서 :

    $ awk '$3=="/aa/bbbb/cccccc"' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

    또는 패턴이 어느 필드에 있는지 모르는 경우

    $ awk '{for(i=1;i<=NF;i++){if($i=="/aa/bbbb/cccccc"){print}}}' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    
  • 펄에서

    $ perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

파일에 두 줄만 있기 때문에 grep -v 'c?' file사용하지 않는 이유 는 무엇입니까? grep -v '?' file
αғsнιη

사실, 나는 약간의 패턴을 유지하고 싶었습니다. 이 경우에는 grep -v '?'충분할 것입니다.
terdon

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