将文件每一行的后半部分替换为另一个文件中的相应部分

ech*_*cho 2 grep sed awk

我有两个文件 A 和 B。两个文件中的每一行都被视为一个项目。每个项目的格式都是固定的,由键和描述组成,并用空格分隔。如下例所示。

UASCH-XCF02-SP062 /users/documents/ark
Run Code Online (Sandbox Code Playgroud)

第一部分UASCH-XCF02-SP062是重点,最后一部分/users/documents/ark是说明。文件 A 和 B 分别有 1000 和 100000 个项目。同一文件中的每个键都是唯一的,但文件 A 中的项的键也出现在文件 B 中,但描述不同。如下一个简单的例子所示。

文件A

UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
Run Code Online (Sandbox Code Playgroud)

文件B

UASCH-XCF02-SP062 /users/documents/ark3
UASCH-XXF02-SP063 /users/documents/ark4
UASCH-XXF03-SP064 /users/documents/ark5
Run Code Online (Sandbox Code Playgroud)

我想将文件B中相同key对应的描述替换为文件A中key对应的描述。示例中的结果如下所示。

文件B

UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
Run Code Online (Sandbox Code Playgroud)

如何实现这个目标?

Dis*_*ian 7

这可以使用 AWK 来完成:

$ awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
Run Code Online (Sandbox Code Playgroud)

编辑:由于 Ed 的评论,简化了 AWK 表达式的后半部分。

要编辑文件 B,请将 AWK 输出重定向到临时文件,然后用它替换文件 B,如下所示:

awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt >B.txt.tmp
mv B.txt.tmp B.tmp 
Run Code Online (Sandbox Code Playgroud)

怎么运行的。我们首先将第一个文件(A)的所有键值对保存到一个关联数组中,使用NR==FNR习惯用法来区分第一个文件和第二个文件。然后,当我们遍历第二个文件 (B) 时,我们将检查当前密钥是否存在于第一个文件中,如果存在,我们将当前值替换为第一个文件中找到的值。