1

我想在几百个日志文件中有效地搜索约 200 个文件名。

grep我可以使用's指令轻松完成此操作-f并将针头放入文件中。

但是,有几个问题:

  • 我有兴趣有效地做到这一点,如如何有效地使用 grep?
  • 我想分别知道所有日志文件中每个搜索词(即文件名)的所有匹配项。grep -f将匹配,因为它在每个文件中找到针。
  • 我想知道文件名何时不匹配。

2.7 i7 MBP 带 16GB 内存

使用grep -ron -f needle *给了我:

access_log-2013-01-01:88298:google
access_log-2013-01-01:88304:google
access_log-2013-01-01:88320:test
access_log-2013-01-01:88336:google
access_log-2013-01-02:396244:test
access_log-2013-01-02:396256:google
access_log-2013-01-02:396262:google

其中needle包含:

google
test

这里的问题是在整个目录中搜索任何匹配项,needle并且该过程是单线程的,因此需要很长时间。也没有关于它是否未能找到匹配项的明确信息。

4

2 回答 2

1

在 bash 脚本中组合grep和怎么样?find

for needle in $(cat needles.txt); do
    echo $needle
    matches=$(find . -type f -exec grep -nH -e $needle {} +)
    if [[ 0 == $? ]] ; then
        if [[ -z "$matches" ]] ; then
            echo "No matches found"
        else
            echo "$matches"
        fi
    else
        echo "Search failed / no matches"
    fi
    echo
done

needles.txt包含目标文件名的列表。

要从文件中逐行读取针(现在可以包含空格),请使用以下版本:

cat needles.txt | while read needle ; do
    echo $needle
    matches=$(find . -type f -exec grep -nH -e "$needle" {} +)
    if [[ 0 == $? ]] ; then
        if [[ -z "$matches" ]] ; then
            echo "No matches found"
        else
            echo "$matches"
        fi
    else
        echo "Search failed / no matches"
    fi
    echo
done

如果您与 进行组合xargs,错误代码 $? 即使成功也不再为零。这可能不太安全,但对我有用:

cat needles.txt | while read needle ; do
  echo $needle
  matches=$(find . -type f -print0 | xargs -0 -n1 -P2 grep -nH -e "$needle")
  if [[ -z "$matches" ]] ; then
        echo "No matches found"
  else
        echo "$matches"
  fi
  echo
done
于 2013-09-25T20:01:29.970 回答
1

要确定哪些针不再匹配,您可以从 grep 获取输出,然后:

  1. 使用 awk 或类似的东西将匹配的字符串提取到单独的文件中。
  2. 将该针文件连接到该文件
  3. sort --uniq filename -o temp1
  4. 将 needles 文件连接到 temp1
  5. sort temp1 -o temp2
  6. uniq -u temp2 > temp3

temp3 将包含不再使用的针。

可能有更简洁的方法来做到这一点。步骤 1 到 3 获取在文件中找到的唯一针的列表。

假设您的 needles 文件包含:

google
foo
bar

并且 grep 在多个文件中找到 foo 和 bar,但没有找到 google。第 1 步将创建一个文件,如:

foo
bar
bar
foo
foo
bar
foo

sort --uniq将创建:

foo
bar

连接 needles 文件给出

foo
bar
google
foo
bar

排序给出:

bar
bar
foo
foo
google

最后的uniq -u命令将输出一行:

google
于 2013-09-25T20:13:22.587 回答