我有一个输入文件,必须在段落中搜索不同的匹配项,并在匹配时移动到输出文件和整个段落。
一件事是,输出的顺序应该反映输入。因此,我必须针对模式匹配文件中的所有模式搜索一个段落(每行一个模式),如果一个模式匹配,它应该停止对该段的进一步匹配,将匹配的段落移动到输出文件,并跳过处理到下一个段落。
输入文件:
DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH
DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH
DFLKHSDFKLH
SDSDJKLFHSDK
OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG
DFSDKLF
YYYYYYYYYYYY
模式匹配文件:
AAAAAAAA
YYYYYYYYYYYY
XXXXXXXXXXXX
预期产出:
DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH
DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH
OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG
DFSDKLF
YYYYYYYYYYYY
我现在正面临着一堆awk
问题,这些问题在我的脑海中挥之不去:
diff
来实现这一点)。发布于 2021-01-05 04:39:35
由于您已经知道了“段落”模式,下面的方法应该有效。它将首先解析“模式”文件,然后解析实际输入。输出照例打印到控制台,但当然可以重定向到文件:
awk -v ORS="\n\n" 'NR==FNR{pat[++npat]=$0;next}
{for (i=1;i<=npat;i++) {if (index($0,pat[i])) {print;next}}}' patterns.txt RS="" input.txt
FNR
,每个文件的行计数器等于NR
,全局行计数器)时,我们只需将所有模式存储在数组变量pat
中。awk
以“段落模式”运行。然后,我们遍历所有模式,并通过index()
函数显式地查看它们是否在输入记录中找到。注
index()
函数是因为这将确保文字字符串匹配,即使在“搜索模式”包含正则表达式特殊字符的情况下也是如此。如果要实际使用正则表达式匹配,请使用if ($0 ~ pat[i])
。发布于 2021-01-05 08:49:31
假设您想要进行全行字符串匹配,这就是您需要的:
$ cat tst.awk
BEGIN {
ORS = "\n\n"
FS = "\n"
}
NR==FNR {
tgts[$0]
next
}
{
out = "unmatched"
for (i=1; i<=NF; i++) {
if ($i in tgts) {
out = "matched"
break
}
}
print > out
}
$ awk -f tst.awk targets RS= file
$ ls *matched
matched unmatched
$ head -100 *matched
==> matched <==
DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH
DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH
OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG
DFSDKLF
YYYYYYYYYYYY
==> unmatched <==
DFLKHSDFKLH
SDSDJKLFHSDK
如果您需要执行regexp而不是字符串匹配和/或部分匹配,而不是完全匹配或其他什么,那么您将需要一个不同的解决方案(请更新您的问题以更好地说明您的需求)。
发布于 2021-01-05 04:39:26
要将match
输入中的模式与infile
输入匹配为单个单独模式,请尝试:
awk -F'\n' '!input && !matches[$0]{ next; };
{ for(i=1; i<=NF; i++) {
if($i in matches) { print sep $0; sep=ORS; break; };
};
}' match input=1 RS= infile
或者,要将match
输入中的模式作为模式块匹配到infile
输入(将一个与match
输入相同的块添加到infile
以进行验证),请尝试:
awk -v RS= '!input && !matches[$0]{ next; }; ($0 in matches)' match input=1 infile
https://unix.stackexchange.com/questions/627613
复制