![키워드에 대한 디렉토리의 각 파일을 grep하고 키워드와 해당 키워드가 있는 파일 이름을 출력하려면 어떻게 해야 합니까?](https://linux55.com/image/151906/%ED%82%A4%EC%9B%8C%EB%93%9C%EC%97%90%20%EB%8C%80%ED%95%9C%20%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%EC%9D%98%20%EA%B0%81%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20grep%ED%95%98%EA%B3%A0%20%ED%82%A4%EC%9B%8C%EB%93%9C%EC%99%80%20%ED%95%B4%EB%8B%B9%20%ED%82%A4%EC%9B%8C%EB%93%9C%EA%B0%80%20%EC%9E%88%EB%8A%94%20%ED%8C%8C%EC%9D%BC%20%EC%9D%B4%EB%A6%84%EC%9D%84%20%EC%B6%9C%EB%A0%A5%ED%95%98%EB%A0%A4%EB%A9%B4%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%ED%95%B4%EC%95%BC%20%ED%95%A9%EB%8B%88%EA%B9%8C%3F.png)
2000개 이상의 텍스트 파일이 포함된 디렉터리가 있습니다. 스크립트를 작성하려고 합니다.
- IP 주소 목록 읽기
ip.txt
- Cats 디렉토리의 모든 파일
- 각 파일의 IP 주소를 파악합니다.
키워드가 발견되면 키워드와 파일 이름이 파일에 반영됩니다.
출력은 다음과 같아야 합니다.
$ cat
results.txt
192.168.2.3 was found in 23233.txt
192.168.4.0 was found in 2323.txt
현재 나는 이것을 가지고 있습니다 :
while read p; do
for filename in *.txt; do
if cat $filename | grep "$p"
then echo "$p" is "$filename" | tee result.txt
fi
done
done<ips.txt
그러나 이렇게 하면 모든 파일 이름도 결과에 반영됩니다. 이 문제를 어떻게 해결할 수 있나요?
답변1
먼저, cat
필요하지 않을 때는 사용하지 말고 저장해 두세요. 대신에:
cat haystack | grep needle
간단히 다음을 수행할 수 있습니다.
grep needle haystack
귀하의 스크립트는 다음과 같습니다.
> results.txt # start with a fresh file for every run
while read ip; do
grep "$ip" * | grep -Ev 'results\.txt|ips\.txt' >> results.txt
done < ips.txt
grep
-into-pipe는 grep
입력 및 출력 파일의 항목이 출력 파일에 추가되는 것을 방지하는 데 사용됩니다.
확인해야 할 수많은 파일이 있고 이를 얻은 경우 명령을 쉘이 허용할 수 있을 만큼 짧은 청크로 분할하는 argument list too long
것과 같은 도구를 사용할 수 있습니다 .xargs
> results.txt # start with a fresh file for every run
while read ip; do
find . -type f -maxdepth 1 -not -name ips.txt -not -name results.txt -print0 | xargs -0 grep "$ip" >> results.txt
done < ips.txt
여기서는 입력 및 출력 파일을 필터링하고 논리적 입력을 사용하므로 더 이상 입력이 find
필요하지 않습니다 .grep
grep
답변2
파일에 IPv4 주소만 있다고 가정하면(IPv6 없음) 다음과 같은 명령을 실행할 수 있습니다.
find [dir1] -maxdepth 1 -type f -iname ip.txt -exec grep -H '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' {} \;
이는 무제한의 파일을 처리해야 합니다. 출력은 다음과 같습니다 [dir1]/ip.txt:1.2.3.4
. 물론 "[dir1]"을 실제 디렉터리로 바꿔야 합니다(또는 이 옵션을 생략할 수 있습니다. 이 경우 find는 현재 작업 디렉터리만 사용합니다). 원하는 경우 여러 디렉터리를 지정할 수 있습니다. 실제로 find 명령에 넣을 수 있는 디렉토리 수에는 실제 제한이 없어야 합니다.앞으로"-최대 깊이" 매개변수.
답변3
grep이 마음에 들지 않는다면 또 다른 옵션은 제가 오래 전에 grep을 대체하는 데 사용했던 가장 좋아하는 도구입니다.확인하다. 이는 귀하가 제공하는 스크립트에 거의 적합하며 필요한 출력을 제공합니다. (기본적으로 재귀적으로 검색하므로 하위 폴더의 파일을 검색하지 않으려는 경우 주목할 가치가 있습니다).
while read p; do
for filename in $(ack -l $p); do
echo "$p found in $filename" >> results.txt
done
done<ips.txt