문자열이 포함된 줄을 찾아 특정 줄과 기타 내용을 인쇄하는 방법

문자열이 포함된 줄을 찾아 특정 줄과 기타 내용을 인쇄하는 방법

다음 명령을 사용하여 여러 파일을 재귀적으로 검색하고 각 파일에서 문자열이 발견된 줄 번호를 찾았습니다.

    grep -nr "the_string" /media/slowly/DATA/lots_of_files > output.txt

출력은 다음과 같습니다.

    /media/slowly/DATA/lots_of_files/lots_of_files/file_3.txt:3:the_string
    /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt:6:the_string is in this sentence.
    /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt:9:the_string is in this sentence too.

위에 표시된 대로 출력에는 파일 이름, 줄 번호 및 줄의 모든 텍스트(문자열 포함)가 포함됩니다.

또한 다음을 사용하여 문자열이 포함된 파일의 특정 줄만 인쇄하는 방법도 알아냈습니다.

    sed '3!d' /media/slowly/DATA/lots_of_files/lots_of_files/file_3.txt > print.txt
    sed '6!d' /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt >> print.txt
    sed '9!d' /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt >> print.txt

줄 번호와 파일 이름을 읽어 수동으로 위 명령을 생성했습니다.

이것이 내 문제입니다.

Q1a

이 두 단계를 하나의 명령으로 결합하는 방법이 있습니까? 줄 번호와 파일 이름을 sed에 연결하고 해당 줄을 인쇄하려고 합니다. grep 출력이 생성되는 순서에 대한 질문이 있습니다.

1분기

위와 동일하지만 문자열이 포함된 줄 앞과 뒤 2줄을 인쇄합니다(총 5줄)? 나는 줄 번호와 파일 이름을 sed에 연결하고 필요한 모든 줄을 어떻게든 인쇄할 생각입니다.

매우 감사합니다.

답변1

질문을 올바르게 이해했다면 grep 명령을 사용하여 이 작업을 수행할 수 있습니다.

Q1a의 경우 grep출력에서 ​​억제된 파일 이름을 사용할 수 있습니다 -h. 예를 들면 다음과 같습니다.

grep -hnr "the_string" /media/slowly/DATA/lots_of_files > output.txt

Q1b의 경우 grep출력에는 사용 및 일치하는 줄 앞뒤에 줄이 포함될 수 있습니다 -A. -B예를 들면 다음과 같습니다.

grep -hnr -A2 -B2 "the_string" /media/slowly/DATA/lots_of_files > output.txt

출력에는 일치 항목 사이에 구분 기호가 포함되며, 이를 사용하여 표시하지 않을 수 있습니다 --no-group-separator. 예를 들면 다음과 같습니다.

grep -hnr -A2 -B2 --no-group-separator "the_string" /media/slowly/DATA/lots_of_files > output.txt

출력에서는 일치 줄( :)과 컨텍스트 줄( -)에 대해 서로 다른 구분 기호를 사용합니다.

답변2

제가 아는 한, 귀하의 첫 번째 질문은 grep다양한 방식으로 답변될 수 있습니다. 파일 목록(또는 -r에서 사용하거나 재귀할 디렉터리 ) 을 보내면 -R줄 번호와 함께 일치하는 항목이 발견된 파일이 항상 출력됩니다. 이 문제를 해결하려면 다음 구성을 사용할 수 있습니다.

find /path/to/files -type f | xargs grep -n 'the_pattern'

두 번째 질문의 경우, 게임 전후의 라인을 보려면 다음을 사용할 수 있습니다 -C.컨텍스트) 스위치:

grep -C2 'pattern' /path/to/file # displays the two lines before and after a match

관련 -C-A(이후) 및 -B(에 대한두번째before), 이는 각각 일치 항목 뒤 또는 앞의 지정된 수의 줄만 제공합니다.

다음과 같이 두 가지 답변을 결합할 수 있습니다.

find /path/to/files -type f | xargs grep -n -C2 'the_pattern'

그것에 대한 귀하의 질문에 관해서는 sed귀하가 제공한 예는 귀하가 이미 줄 번호를 알고 있는 경우에만 작동합니다. 다음과 같이 할 수도 있습니다.

sed -n '/the_pattern/p' /path/to/files/*

(그러나 하위 디렉토리로 재귀되지는 않습니다)

답변3

find /media/slowly/DATA/lots_of_files -type f -exec grep -h -C2 'the_pattern' {} +

/media/slowly/DATA/lots_of_files 디렉토리에서 파일(디렉토리나 링크가 아님)을 찾습니다. 이를 그룹화하고(이 10년 동안 xargs가 필요 없음) grep을 실행합니다. grep은 파일 이름(-h)을 인쇄하지 않지만 일치하는 줄 앞뒤에 2줄의 컨텍스트를 제공합니다(-C2, 보다 정확한 제어를 위해 -A 및 -B 사용).

@cherdt의 명령과 비교할 때 이 명령의 장점은 find 명령에 추가 필터를 추가할 수 있다는 것입니다. 예를 들어 다음과 같은 디렉토리에 들어가지 않도록 선택할 수 있습니다..git

관련 정보