Unix 命令在另一个 file2 中搜索 file1 id 并将结果写入 file3

Unix command to search file1 id in another file2 and write result to a file3

我必须从一个文件中读取 ID 并在第二个 xml 文件中搜索它,如果找到则将整行写入第三个文件。文件 1 为 111 MB,文件 2 为 40 GB

File1.xml

id1
id2
id5

File2.xml

<employees>
<employee><id>id1</id><name>test1</name></employee>
<employee><id>id2</id><name>test2</name></employee>
<employee><id>id3</id><name>test3</name></employee>
<employee><id>id4</id><name>test4</name></employee>
<employee><id>id5</id><name>test5</name></employee>
<employee><id>id6</id><name>test6</name></employee>
</employees>

File3.xml : 结果

<employee><id>id1</id><name>test1</name></employee>
<employee><id>id2</id><name>test2</name></employee>
<employee><id>id5</id><name>test5</name></employee>

我用 grep 试过了

grep -i -f file1.xml file2.xml >> file3.xml

但它给出内存耗尽错误。

我用循环和 awk 命令尝试的另一种方法。

#while read -r id;do
#awk  -v pat="$id" '[=14=]~pat' file2.xml  >> file3.xml
#done < file1.xml

它也花了太多时间。 最好的解决方案是什么。

使用您显示的示例,请尝试以下 awk 代码。在 GNU awk.

中编写和测试
awk -v FPAT='<id>[^<]*</id>' '
FNR==NR{
  arr["<id>"[=10=]"</id>"]
  next
}
( in arr)
' file1.xml file2.xml

解释:为以上添加详细解释。

awk -v FPAT='<id>[^<]*</id>' '   ##Starting awk program and setting FPAT to <id>[^<]*<\/id>
FNR==NR{                         ##Checking condition which will be TRUE when file1.xml is being read.
  arr["<id>"[=11=]"</id>"]           ##Creating an array arr which has index of <id> [=11=] </id> here.
  next                           ##next will skip all further statements from here.
}
( in arr)                      ##Checking condition if  is present in arr then print that line.
' file1.xml file2.xml            ##Mentioning Input_file names here.

这应该适用于任何 awk 版本:

awk 'FNR == NR {
   seen["<id>"  "</id>"]
   next
}
match([=10=], /<id>[^<]*<\/id>/) && substr([=10=], RSTART, RLENGTH) in seen
' file1 file2

<employee><id>id1</id><name>test1</name></employee>
<employee><id>id2</id><name>test2</name></employee>
<employee><id>id5</id><name>test5</name></employee>