Linux awk grep 从文件1到文件2

Linux awk grep 从文件1到文件2

我在文件 1 中有正则表达式

.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*

还有很多其他文件包含如下记录:

0081347504;03.05.2019 10:51;000010;000000001000126289;8601;Kontaktschreiben;;;;;00000000000901326394;
0081349117;03.05.2019 10:51;000020;000000002000044721;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332422;
0081349117;03.05.2019 10:51;000030;000000002000044722;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332423;
0081351563;03.05.2019 10:52;000010;000000001000116607;8906;Termin vereinbaren;;;06.05.2019;13:00;18:00;00000000000901332339;

我想要grep文件 2 中文件 1 中的每条记录。

我已经尝试过grep -Ff file 1 ./*但不起作用。

答案1

稍微整洁一点也没什么坏处。

首先,我认为你可能感到困惑regexesGlobbing;并且无论哪一行,您都不需要重复同一行两次或更多次(可能您试图表明您有很多行要解释为regexes,但您懒得使每一行都唯一...但是,只是为了确定)。所以这:

.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*

可以用这个代替:

.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*

好吧...现在怎么办?...好吧,grep它会将每一行用作 a regex(不globbingon grep),因此,该文件中的每一行都应该是 a regex,... 因此,如果您尝试匹配:

891281415444

在哪里代表:任何事物

这:

.*8912.*81415444.*

就足够了。

然后,在您的文件中使用它regex

.*8912.*81415444.*
.*8802.*84231655.*

但是,如果您想匹配:

8912 81415444

在哪里代表:任何事物代表文字点,这regex是错误的,因为在 中regexes,一个点是一个meta-character...你需要逃离每一个文字点带有backslash> \,所以,正则表达式应该是:

\..*8912\..*\..*\..*\..*81415444\..*

然后,在您的文件中使用它regex

\..*8912\..*\..*\..*\..*81415444\..*
\..*8802\..*\..*\..*\..*84231655\..*

或者,您可以使用egrep与 相同的grep --extended-regexp,来使用扩展正则表达式,并简化你的正则表达式限制重复,并以更紧凑的方式与上面完全相同,如下所示:

\..*8912(\..*){4}81415444\..*
\..*8802(\..*){4}84231655\..*

(您可以在没有扩展正则表达式的情况下执行类似的操作,但您需要使用更多反斜杠,如下所示\..*8912\(\..*\)\{4\}81415444\..*:)

现在,假设您位于一个包含两个目录的目录中:一个是正则表达式(带有正则表达式文件的一个),另一个是样本文件(包含您想要与正则表达式匹配的文件的文件)...

然后,您可以使用此命令来实现您的目标:

grep --colour -f ./regex/YOUR_REGEX_FILENAME ./sample_files/*

你会得到一些输出,如下所示:

./sample_files/sample_file2:0088027504;03.05.2019 10:51;000010;000000008423165589;8601;Kontaktschreiben;;;;;00000000000901326394;
./sample_files/sample_file7:0089128117;03.05.2019 10:51;000030;000000002814154447;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332423;

你可能会说:为什么有两个单独的目录?好吧,这并不是真正必要的,但是,问题是,如果您的示例文件和正则表达式文件位于同一目录中,并且您使用如下命令:

grep -f file_1 ./*

./*是使用通配符,并将匹配当前目录中的任何文件,包括您的正则表达式文件...

在这种情况下,您可以做的是,例如,向您的正则表达式文件添加一些独特的扩展名,例如,,.regex然后更改此文件的通配模式:./!(*.regex)...此通配将排除以 ... 结尾的文件.regex,然后,你的命令是:

grep -f file_1.regex ./!(*.regex)

最后,请注意:您不能在 shell 中使用带有空格的名称,而不转义它们:您可以使用反斜杠转义每个空格,或者可以用引号将全名括起来。

答案2

除了 matsib.dev 的出色回答之外:

您确定 -F 标志吗?它关闭正则表达式并让 grep 搜索固定字符串。因此.*只会命中包含点后跟星号的行。

另一件需要检查的事情是文件的内容1。如果它具有类似 dos 的行结尾(即行以 CRLF 而不是单个 LF 结尾),grep -f 1则将搜索以 CR 或 ^M 结尾的字符串。检查这一点的最快方法:cat -A 1。如果您在每行末尾看到 ^M,则说明您有问题。

相关内容