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