通过重新格式化保存有价值数据的分区,我设法向自己的痛处(非常糟糕)开枪。当然这不是故意的,但是却发生了。
然而,我设法使用testdisk
并photorec
恢复了大部分数据。现在我已经将所有数据分布在近 25,000 个目录中。大多数文件是.txt 文件,其余的是图像文件。每个目录中有超过300个.txt文件。
我可以grep
或使用find
从 .txt 文件中提取某些字符串并将其输出到文件中。例如,我用下面的一行来验证我的数据是否位于恢复的文件中:
find ./recup*/ -name '*.txt' -print | xargs grep -i "searchPattern"
我可以将“searchPattern”输出到文件中,但这只是给了我该模式。这就是我真正想要实现的目标:
浏览所有文件并查找特定字符串。如果在文件中找到该字符串,则将该文件的所有内容 cat 到输出文件。如果在多个文件中找到该模式,则将后续文件的内容附加到该输出文件。请注意,我只是不想输出我正在搜索的模式,而是输出找到模式的文件的所有内容。
我认为这是可行的,但我只是不知道如何在从中 grep 特定模式后获取文件的所有内容。
答案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 选项来使用文件名之间的空字节而不是换行符。
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
根据你的 shell 和环境,你可以这样(在 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)