貴重なデータを保持するパーティションを再フォーマットすることで、痛むところ(本当に悪い)に自分を撃つことができました。もちろんそれは意図的なものではありませんでしたが、起こりました。
しかし、私はtestdisk
とphotorec
を使用してほとんどのデータを回復することができました。これで、すべてのデータがほぼ25,000のディレクトリに分散されました。ほとんどのファイルは.txtファイルで、残りは画像ファイルです。各ディレクトリには300を超える.txtファイルがあります。
grep
またはfind
を使用して、.txtファイルから特定の文字列を抽出し、ファイルに出力できます。たとえば、次の行は、データが復元されたファイルにあることを確認するために使用しました。
find ./recup*/ -name '*.txt' -print | xargs grep -i "searchPattern"
「searchPattern」をファイルに出力することはできますが、そのパターンが得られるだけです。これが私が本当に達成したいことです:
すべてのファイルを調べ、特定の文字列を探します。その文字列がファイルで見つかった場合、そのファイルのすべての内容を出力ファイルにcatします。パターンが複数のファイルで見つかった場合は、後続のファイルの内容をその出力ファイルに追加します。検索しているパターンを出力したくないだけで、パターンが見つかったファイルのすべての内容を出力したいことに注意してください。
これは可能だと思いますが、特定のパターンをそこからgrepした後で、ファイルのすべての内容を取得する方法がわかりません。
私があなたの目標を正しく理解していれば、以下はあなたが望むことをします:
find ./recup*/ -name '*.txt' -exec grep -qi "searchPattern" {} \; -exec cat {} \; > outputfile.txt
これにより、*.txt
内のすべての./recup*/
ファイルが検索され、各ファイルがsearchPattern
と一致する場合は、cat
に対してテストされます。すべてのcat
edファイルの出力は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
と一致しないようにするためのものです。
パターンを出力するのではなく、grepで「-l」を使用してファイル名を出力し、それをcatへの入力として使用します。
find ./recup*/ -name '*.txt' -print | xargs grep -li "searchPattern" | xargs cat
または
cat $( find ./recup*/ -name '*.txt' -print | xargs grep -li "searchPattern")
残りの詳細を記入できると思います。ところで、ファイル名にスペースやその他の奇妙な文字が含まれている可能性がある場合(この特定のケースではそうではないが、将来の目的のため)、検索で-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
他の回答とは異なり、これには2つのステップと一時ファイルがあるため、検索するパターンが複数ある場合にのみお勧めします。
シェルと環境に応じて、次のようにすることができます(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)