find를 사용하여 찾은 파일의 내용을 단일 파일로 분류하려면 어떻게해야합니까? 출력을 특정

귀중한 데이터를 보유한 파티션을 재 포맷하여 문제가있는 부분 (실제로 나쁜 부분)을 직접 촬영했습니다. 물론 의도적이지는 않았지만 일어났습니다.

그러나 대부분의 데이터 를 사용 testdisk하고 photorec복구했습니다. 이제 모든 데이터가 거의 25,000 개의 디렉토리에 분산되어 있습니다. 대부분의 파일은 .txt 파일이고 나머지는 이미지 파일입니다. 각 디렉토리에는 300 개가 넘는 .txt 파일이 있습니다.

나는 수 grep사용하거나 find파일로 .txt 인 파일과 출력을 특정 문자열을 추출 할 수 있습니다. 예를 들어, 다음은 데이터가 복구 된 파일에 있는지 확인하는 데 사용한 줄입니다.

find ./recup*/ -name '*.txt' -print | xargs grep -i "searchPattern"

“searchPattern”을 파일로 출력 할 수는 있지만 그 패턴 만 알려줍니다. 내가 정말로 성취하고 싶은 것은 다음과 같습니다.

모든 파일을 살펴보고 특정 문자열을 찾으십시오. 해당 문자열이 파일에서 발견되면 해당 파일의 모든 내용을 출력 파일로 분류하십시오. 패턴이 둘 이상의 파일에서 발견되면 후속 파일의 내용을 해당 출력 파일에 추가하십시오. 검색하려는 패턴을 출력하고 싶지는 않지만 패턴이있는 파일의 모든 내용을 출력하고 싶습니다.

나는 이것이 가능하다고 생각하지만 파일에서 특정 패턴을 잡은 후 파일의 모든 내용을 얻는 방법을 모른다.



답변

목표를 올바르게 이해하면 다음이 원하는 것을 수행합니다.

find ./recup*/ -name '*.txt' -exec grep -qi "searchPattern" {} \; -exec cat {} \; > outputfile.txt

*.txt파일의 모든 파일을 찾고 파일 과 일치하는 경우 ./recup*/각 파일을 테스트 합니다. 모든 ed 파일 의 출력은 로 보내집니다 .searchPatterncatcatoutputfile.txt

각 패턴 및 출력 파일에 대해 반복하십시오.


일치하는 디렉토리가 매우 많으면로 ./recup*끝날 수 있습니다 argument list too long error. 이 문제를 해결하는 간단한 방법은 다음과 같이하는 것입니다.

find ./ -mindepth 2 -path './recup*.txt' -exec grep -qi "searchPattern" {} \; -exec cat {} \; > outputfile.txt

이것은 전체 경로와 일치합니다. 그래서 ./recup01234/foo/bar.txt일치한다. 는 -mindepth 2일치하지 않도록이다 ./recup.txt, 또는 ./recup0.txt.


답변

패턴을 출력하는 대신 grep에서 “-l”을 사용하여 파일 이름을 출력 한 다음 cat의 입력으로 사용하십시오.

find ./recup*/ -name '*.txt' -print | xargs grep -li "searchPattern" | xargs cat

또는

cat $( find ./recup*/ -name '*.txt' -print | xargs grep -li "searchPattern")

나머지 세부 정보를 입력 할 수있을 것 같습니다. BTW, 파일 이름에 공백이나 다른 홀수 문자가있을 수있는 경우 (이 경우는 아니지만 향후 목적으로) 찾기에 -print0을 사용하고 grep에 -Z를 사용하고 xargs의 -0 옵션을 사용하여 사용하십시오 줄 바꿈이 아닌 파일 이름 사이의 null 바이트입니다.

find ./recup*/ -name '*.txt' -print0 | xargs -0 grep -Zli "searchPattern" | xargs -0 cat

답변

이것은 최적의 코드는 아니지만 매우 간단하며 효율성이 문제가되지 않으면 제대로 작동합니다. 문제는 파일에서 이미 문자열을 찾았더라도 파일을 여러 번 통과시키는 것입니다.

먼저 문자열을 검색하고 일치하는 파일을 목록에 씁니다.

find ./recup*/ -name '*.txt' -execdir grep -il "searchPattern" {} >> /tmp/file_list \;

searchPattern필요에 따라 교체하면서이 단계를 반복 하십시오. 에 일치하는 파일 목록이 생성됩니다 /tmp/file_list.

문제는이 파일에 중복 된 파일이있을 수 있다는 것입니다. 따라서 복제본을로 대체 할 수 있습니다 |sort|uniq. sort그 때문에 일부는 서로 인접한 중복 배치 uniq를 제거 할 수 있습니다. 그런 다음 각 파일 이름을 개행 문자로 구분 cat하여 이러한 파일을 함께 사용할 수 있습니다 . 그 후,xargs\n

</tmp/file_list sort | uniq | xargs -d "\n" cat > final_file.txt

다른 답변과 달리 여기에는 두 단계와 임시 파일이 있으므로 여러 패턴을 찾은 경우에만 권장합니다.


답변

쉘과 환경에 따라 다음과 같이 할 수 있습니다 (bash)

while IFS= read -r -d '' file; do
  if grep -qim1 'searchPattern1\|searchPattern2\|searchPattern3' "$file"; then
    cat "$file" >> some/other/file
  fi
done < <(find ./recup*/ -name '*.txt' -print0)

패턴에 따라 결과를 분리하려면 다음과 같이 수정하십시오.

while IFS= read -r -d '' file; do
  if grep -qim1 'searchPattern1' "$file"; then
    cat "$file" >> some/other/file1
  elif grep -qim1 'searchPattern2' "$file"; then
    cat "$file" >> some/other/file2
  elif grep -qim1 'searchPattern3' "$file"; then
    cat "$file" >> some/other/file3
  fi
done < <(find ./recup*/ -name '*.txt' -print0)