首页 > 解决方案 > LINUX 中的文件搜索

问题描述

我有两个文件,FILE1其中包含很多行和FILE2KEY VALUE参数。我需要比较FILE2FILE1如果匹配,FILE1则应将 in 中的相应单词替换为FILE2.

例子:

文件1:

<SOME YAML CODE
-------------->
PARM1
value:PARM2
PARM3
somyaml_PARM4
<END OF YAML CODE
---------------->

文件2:

PARM1 mmddyy
PARM2 hhmmss
PARM3 awsid
PARM4 cc

FILE2因此,对于in 中的每个匹配FILE1项,FILE1 中的相应单词应替换为 in 中的第二列FILE2。所以所需的输出应该是:

<SOME YAML CODE
-------------->
**mmddyy**
value:**hhmmss**
**awsid**
somyaml_**cc**
<END OF YAML CODE
---------------->

在其他社区的帮助下,我能够在命令下运行,但它仅在搜索条件位于行首时才有效

awk '
    NR==FNR{k[$1]=$2;}
    NR!=FNR{if($1 in k){$0=k[$1]};print}
' file2 file1

标签: pythonbashshellawk

解决方案


即使您的 PARM 值是其他 PARM 值的子集,或者包含正则表达式元字符的 PARM 或包含反向引用或递归定义的替换字符串(其中 PARM1 映射到 PARM2 和 PARM2 到 PARM1),这也将满足您的需求。如果 file2 定义了一个 PARM 到另一个 PARM 的映射,那么这只是按照最长优先顺序进行映射。它对 sorted_in 使用 GNU awk,因此我们可以按最长优先顺序访问 PARM 以正确处理子集 - 如果您没有 GNU awk,则在 awk 脚本之外执行 file2 的排序。

$ cat tst.awk
BEGIN {
    PROCINFO["sorted_in"] = "@val_num_desc"
}
NR==FNR {
    map[$1] = $2
    len[$1] = length($1)
    next
}
{
    for ( old in len ) {
        new = map[old]
        head = ""
        tail = $0
        while ( s=index(tail,old) ) {
            head = head substr($0,1,s-1) new
            tail = substr(tail,s+len[old])
        }
        $0 = head tail
    }
    print
}

$ awk -f tst.awk file2 file1
<SOME YAML CODE
-------------->
mmddyy
value:hhmmss
awsid
somyaml_cc
<END OF YAML CODE
---------------->

问题中提供的示例并不好,因为它仅涵盖最基本的晴天情况,其中 file2 中的所有字符串都是唯一的并且仅由字母数字字符组成。更好的测试在第一个字符串中使用正则表达式元字符、作为其他字符串子集的字符串以及在替换字符串中使用反向引用元字符,例如:

$ head file1 file2
==> file1 <==
<SOME YAML CODE
-------------->
A.B
value:A.BX
PARM3
somyaml_PARM4
<END OF YAML CODE
---------------->

==> file2 <==
A.B mmddyy
A.BX hhmmss
PARM3 a\1b&c
PARM4 cc

$ awk -f tst.awk file2 file1
<SOME YAML CODE
-------------->
mmddyy
value:hhmmss
a\1b&c
somyaml_cc
<END OF YAML CODE
---------------->

这仍然缺少需要考虑的情况,例如 file2 包含递归映射,甚至只是从一个“PARM”字符串到另一个的一次性映射:

$ head file1 file2
==> file1 <==
<SOME YAML CODE
-------------->
PARM1
value:PARM2
PARM3
somyaml_PARM4
<END OF YAML CODE
---------------->

==> file2 <==
PARM1 mmddyy
PARM2 hhmmss
PARM3 PARM4
PARM4 PARM3

$ awk -f tst.awk file2 file1
<SOME YAML CODE
-------------->
mmddyy
value:hhmmss
PARM4
somyaml_PARM4
<END OF YAML CODE
---------------->

但这没有在问题中讨论,所以我不知道这是否是预期的输出,如果不是,预期的输出会是什么以及为什么 - 如果您需要处理该问题或任何其他非-更新问题小事不一样。


推荐阅读