私は貴重なデータを含むパーティションを再フォーマットして、病気の場所(非常にひどく)を自分で撮影することができました。もちろん意図したものではありませんでしたが、そのようなことが起こりました。
しかし、ほとんどのデータを使用し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*
1つのディレクトリで終わることができます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
他の回答とは異なり、ここには2つのステップと一時ファイルがあるため、検索するパターンが複数ある場合にのみお勧めします。
答え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)