나는 귀중한 데이터가 들어 있는 파티션을 다시 포맷하여 아픈 곳(매우 심하게)을 스스로 촬영할 수 있었습니다. 물론 의도한 것은 아니었지만 그런 일이 일어났습니다.
그러나 대부분의 데이터를 사용 testdisk
하고 복구 했습니다 . photorec
이제 모든 데이터가 거의 25,000개의 디렉터리에 분산되어 있습니다. 대부분의 파일은 .txt 파일이고 나머지는 이미지 파일입니다. 각 디렉터리에는 300개 이상의 .txt 파일이 있습니다.
grep
.txt 파일에서 특정 문자열을 추출하고 .txt를 사용하여 find
파일로 출력할 수 있습니다. 예를 들어 다음 줄을 사용하여 내 데이터가 복구된 파일에 있는지 확인합니다.
find ./recup*/ -name '*.txt' -print | xargs grep -i "searchPattern"
"searchPattern"을 파일로 출력할 수 있지만 이는 단지 패턴만 제공할 뿐입니다. 이것이 내가 정말로 달성하고 싶은 것입니다:
모든 파일을 탐색하고 특정 문자열을 찾으십시오. 파일에서 문자열이 발견되면 파일의 전체 내용을 출력 파일로 변환합니다. 패턴이 여러 파일에서 발견되면 후속 파일의 내용이 이 출력 파일에 추가됩니다. 내가 찾고 있는 패턴을 출력하는 것이 아니라 패턴이 발견된 파일의 전체 내용을 출력하고 싶다는 점에 유의하세요.
나는 이것이 가능하다고 생각하지만 파일에서 특정 패턴을 파악한 후 파일의 모든 내용을 얻는 방법을 모르겠습니다.
답변1
귀하의 목표를 올바르게 이해하면 다음과 같이 원하는 것을 얻을 수 있습니다.
find ./recup*/ -name '*.txt' -exec grep -qi "searchPattern" {} \; -exec cat {} \; > outputfile.txt
*.txt
그러면 의 모든 파일을 찾고 ./recup*/
, 각 파일을 테스트하고 searchPattern
, 일치하면 해당 cat
파일을 찾습니다. 모든 ed 파일의 출력 cat
은 outputfile.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
.
답변2
패턴을 출력하는 대신 grep에서 "-l"을 사용하여 파일 이름을 출력한 다음 cat에 대한 입력으로 사용할 수 있습니다.
find ./recup*/ -name '*.txt' -print | xargs grep -li "searchPattern" | xargs cat
또는
cat $( find ./recup*/ -name '*.txt' -print | xargs grep -li "searchPattern")
나머지 세부 사항은 귀하가 작성해 주실 수 있을 것 같습니다. 그런데, 파일 이름에 공백이나 기타 이상한 문자가 있을 수 있는 경우(이 특별한 경우는 아니지만 향후 목적을 위해) find에서 -print0을 사용하고, grep에서 -Z를 사용하고, xargs에서 -0 옵션과 결합하여 null을 사용합니다. 개행 대신 파일 이름 사이에 바이트를 추가합니다.
find ./recup*/ -name '*.txt' -print0 | xargs -0 grep -Zli "searchPattern" | xargs -0 cat
답변3
이것은 정확히 최적의 코드는 아니지만 매우 간단하고 효율성이 문제가 되지 않는 경우 잘 작동합니다. 문제는 문자열이 파일에서 이미 발견된 경우에도 파일을 여러 번 grep한다는 것입니다.
먼저 문자열을 검색하고 일치하는 파일을 목록에 작성합니다.
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
다른 답변과 달리 여기에는 두 단계와 임시 파일이 있으므로 찾을 패턴이 여러 개인 경우에만 권장됩니다.
답변4
쉘과 환경에 따라 이 작업을 수행할 수 있습니다(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)