여러 파일에서 마지막 일치 항목을 얻으려면 Grep 및 find를 사용하세요.

여러 파일에서 마지막 일치 항목을 얻으려면 Grep 및 find를 사용하세요.

두 파일에 다음 내용이 있다고 가정합니다.

$ cat ttest1.txt 
x = 1
x = 3
y = 5
$ cat ttest2.txt 
x = 4
x = 10
y = 3

x파일을 재귀적으로 grep 하고 각 파일의 마지막 인스턴스를 인쇄하고 싶습니다 . 따라서 원하는 출력은 다음과 같습니다.

ttest1.txt:x = 3
ttest2.txt:x = 10

다음과 의 grep조합은 tail하나의 파일에 대해 작동하지만 여러 파일에 대해서는 작동하지 않습니다.

$ grep x ttest1.txt 
x = 1
x = 3
$ grep x ttest1.txt | tail -n 1
x = 3
$ grep -r x ttest* | tail -n 1
ttest2.txt:x = 10

이 문제를 어떻게 해결할 수 있나요?

답변1

당신이 할 때

grep -r x ttest* 

당신은 스트림을 얻습니다

ttest1.txt:x = 1
ttest1.txt:x = 3
ttest2.txt:x = 4
ttest2.txt:x = 10

이렇게 하면 예상한 대로 tail -1입니다 ttest2.txt:x = 10.

grep | tail그러나 병합된 스트림이 아닌 각 개별 파일에서 결합이 수행되기를 원합니다 . 따라서 각 개별 파일에 대해 이 작업을 수행하십시오.

for f in ttest* ; do
    grep x "$f" | tail -n 1
done

답변2

를 사용하면 awk정규식 문자열을 사용할 수 있습니다(참조:동적 정규식), 각 입력 파일의 마지막 일치 항목을 기억하고 인쇄합니다.

$ awk -v regex="x" 'FNR==1 && m!=""{print m;m=""} 
        $0 ~ regex{m=FILENAME ":" $0}
        END{if (m!="")print m}' ttest*
ttest1.txt:x = 3
ttest2.txt:x = 10

다음과 재귀적으로 결합됩니다 find.

$ find . -name 'ttest*' -type f -exec awk -v regex="x" '
        FNR==1 && m!=""{print m;m=""}
        $0 ~ regex{m=FILENAME ":" $0}
        END{if (m!="")print m}' {} +
./ttest1.txt:x = 3
./ttest2.txt:x = 10

답변3

GNU sed 사용:

sed -sn '/x/h; $ { x; F; p; }' ttest*

산출:

ttest1.txt
x = 3
ttest2.txt
x = 10

paste -d: - -결과를 한 행에 표시하려면 이 옵션을 전달하세요. -change 명령 x뒤에 검사가 포함되지 않은 파일에서 출력 하지 않으려는 경우 x예를 들면 다음과 같습니다.{ x; /./ { F; p; z; }; }

답변4

한 가지 방법은 다음과 같습니다.

grep  x <yourpath>*  | tac | awk  'BEGIN{FS=":"};seen!=$1{print $0;seen=$1}'

tac은 awk 작업을 준비하기 위해 grep 결과를 뒤집은 다음 각 파일에서 첫 번째 일치 항목만 인쇄합니다.

관련 정보