如何打印没有匹配行的输入模式?

Was*_*haW 5 grep text-processing

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

grep -oiE 'pattern1|pattern2|pattern3|pattern4' *pattern_in_a_filename* | sort -u
Run Code Online (Sandbox Code Playgroud)

输出:

file_one:pattern1
file_two:pattern2
file_two:pattern3
Run Code Online (Sandbox Code Playgroud)

我想要的是pattern4像这个例子一样输出没有被发现的说法:

file_one:pattern1
file_two:pattern2
file_two:pattern3
pattern4 not found
Run Code Online (Sandbox Code Playgroud)

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

Rom*_*est 6

它做的

想要尽快完成任务吗?

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

正确的方法是将所有模式放入文件中,例如patterns.txt.

关键工作:

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

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

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

得出你的结论...

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


cev*_*ing 5

该工具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
Run Code Online (Sandbox Code Playgroud)

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

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

$ pattern='a|b|d'
Run Code Online (Sandbox Code Playgroud)

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

$ found=($(grep -hoiE "$pattern" x* | sort -u))
Run Code Online (Sandbox Code Playgroud)

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

$ new_pattern="$(IFS='|' ; echo "${found[*]}")"
Run Code Online (Sandbox Code Playgroud)

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

$ data="${pattern//|/$'\n'}"
Run Code Online (Sandbox Code Playgroud)

然后这是不匹配的模式列表:

$ grep -viE "$new_pattern" <<< "$data"
d
Run Code Online (Sandbox Code Playgroud)


ces*_*arv 2

这是一个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
Run Code Online (Sandbox Code Playgroud)

在此脚本中,我假设您将结果输出到文件 grepfound.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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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