我有一个包含 2000 多个文本文件的目录。我正在尝试制作一个脚本:
- 从以下位置读取 IP 地址列表
ip.txt
- Cats目录中的每个文件
- greps 每个文件的 IP 地址
如果找到关键字,则将关键字和文件名回显到文件中。
输出应该是这样的:
$ cat
results.txt
192.168.2.3 was found in 23233.txt
192.168.4.0 was found in 2323.txt
目前我有这个:
while read p; do
for filename in *.txt; do
if cat $filename | grep "$p"
then echo "$p" is "$filename" | tee result.txt
fi
done
done<ips.txt
但是,这也会将所有文件名回显到结果中。我怎样才能解决这个问题?
首先,
cat
当你不需要它时,不要使用它来保存它。而不是:您可以简单地:
至于你的脚本:
-into
grep
-grep
pipeline 是为了防止将输入和输出文件中的条目添加到输出文件中。如果你有无数的文件要检查并且你得到了
argument list too long
,我们可以使用一个工具,比如xargs
将我们的命令分解成足够短的块,以便 shell 允许:在这里,我们过滤掉带有逻辑的输入和输出文件 into
find
,因此我们不再需要grep
intogrep
。假设您的文件只有 IPv4 地址(没有 IPv6),您可以运行如下内容:
find [dir1] -maxdepth 1 -type f -iname ip.txt -exec grep -H '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' {} \;
这应该处理无限数量的文件。您的输出将类似于
[dir1]/ip.txt:1.2.3.4
. 当然,您需要将“[dir1]”替换为实际目录(或者您可以省略此选项,在这种情况下 find 将只使用您当前的工作目录)。如果您愿意,可以指定多个目录。实际上,只要将它们放在“-maxdepth”参数之前,就可以在 find 命令中放置多少个目录不应该有任何真正的限制。另一种选择,如果你没有为此与 grep 结婚,我最喜欢的工具是我很久以前用来替换 grep 的 - ack。它几乎可以放入您提供的脚本并提供您需要的输出。(默认情况下它是递归搜索,如果您不想搜索子文件夹中的文件,请注意)。