如何打印输入的没有匹配行的图案?

如何打印输入的没有匹配行的图案?

我有这个 grep 命令来查找具有匹配模式的文件。

grep -oiE 'pattern1|pattern2|pattern3|pattern4' *pattern_in_a_filename* | sort -u

输出:

file_one:pattern1
file_two:pattern2
file_two:pattern3

我想要的是输出pattern4未找到的说法,如下例所示:

file_one:pattern1
file_two:pattern2
file_two:pattern3
pattern4 not found

我正在制作成千上万的图案,并且必须尽快完成,因为这些是我们运营中所需的关键数据。

答案1

它必须这样做快的尽可能

想要尽快完成事情吗?

发现并行处理并应用以下 GNUparallel解决方案:

正确的方法是从将所有模式放入文件开始,比方说patterns.txt

关键工作:

cat patterns.txt | parallel -j 0 --no-notice 'grep -Hoi {} /path/to/files/* || echo "{} not found"' | sort -u
  • -j N- 职位数量。并行运行N作业。0意思是尽可能多。默认值为 100%,即每个 CPU 核心运行一个作业。

上述命令将搜索每个图案patterns.txt所有文件中并行。

我做了一个测试,只有2CPU 核心,包含一些模式列表和一些每个 641 Mb 的 csv 文件。我有大约470%与连续处理相比,时间速度有所提高。
您的计算机拥有的 CPU 核心越多,您达到的速度性能就越快。

得出你的结论...

https://www.gnu.org/software/parallel/man.html

答案2

该工具grep按模式搜索文件。这意味着模式是输入,文件是输出。这意味着您可以使用 grep 找到的只是文件,而不是模式。

为了找到那些不包含匹配模式的文件,您必须使用-v.这需要两次调用。

例子:

$ echo a > xa
$ echo ab > xab
$ echo c > xc
$ { grep -oiE 'a|b' x*; grep -vl -E 'a|b' x*; } | sort -u
xa:a
xab:a
xab:b
xc

为了找到那些不匹配的模式,您必须将模式作为输入,将搜索结果作为模式。匹配列表成为模式,模式成为您必须在其中进行搜索的数据。

我们假设这可能是前面示例中的文件的模式。

$ pattern='a|b|d'

然后将匹配模式列表存储在数组中:

$ found=($(grep -hoiE "$pattern" x* | sort -u))

这会将数组转换为新模式:

$ new_pattern="$(IFS='|' ; echo "${found[*]}")"

这会将原始模式转换为数据:

$ data="${pattern//|/$'\n'}"

这是不匹配的模式列表:

$ grep -viE "$new_pattern" <<< "$data"
d

答案3

这是实现您期望的方法。既然你说你有数千种模式,所以我假设你喂养图案从文件中获取,那么这比直接传递要好得多图案grep。命令如下。

grep -oif ../patt_file file* && 
    printf "%s Not Found.\n" $(grep -vFxf <(grep -oihf ../patt_file file*) \
    <(< ../patt_file))

为了避免匹配图案文件patt_file本身,您需要将其移动到与输入infiles*所在的目录不同的目录。

答案4

这是一个sh生成您需要的结果的脚本。

#!/bin/sh

grep -f /path/to/patterns.txt /path/to/*_856_2017* | sort -u > /path/to/foundFiles.txt 

while read -r LINE
do
    grep -F "$LINE" /path/to/foundFiles.txt
    if [ $? -eq 1 ]
    then
        echo "$LINE" not found
    fi
done < /path/to/patterns.txt

在此脚本中,我假设您输出的结果你的 grep到文件found.txt,并且将模式存储在文件中/path/to/foundFiles.txt

正如您所看到的,grepin 循环将生成文件的相同内容,found.txt同时添加"$pattern" not found丢失的内容。

我还为您的案例设计了第二种方法:

#!/bin/sh

grep -f /path/to/patterns.txt /path/to/*_856_2017* |
    sort -u > /path/to/foundFiles.txt

comm -23 /path/to/patterns.txt /path/to/foundFiles.txt |
    xargs -L 1 -I {} echo {} not found > /path/to/notFoundFiles.txt

cat /path/to/foundFiles.txt /path/to/notFoundFiles.txt > /path/to/finalList.txt

在这种情况下,patterns.txt需要已经排序才能comm工作。

comm命令比较两个文件,返回仅在patterns.txt(-23参数) 中出现的行,这是 未找到的模式列表grep

然后,xargs抓取每一行 ( -L 1) 并回显该行 ( {}) 并附加“未找到”。结果xargs被重定向到notFoundFiles.txt文件。

最后,您只需将 findFiles.txt 和 notFoundFiles.txt 连接到finalList.txt.

相关内容