使用shell脚本从两个列表中提取数据

时间:2011-12-22 01:54:42

标签: linux bash shell

我正在尝试创建一个shell脚本,该脚本从文件中提取一行并检查另一个文件以获取相同的实例。如果找到一个条目,则将其添加到另一个文件并循环遍历第一个列表,直到它遍历整个文件。第一个文件中的数据如下所示 -

email@address.com;
email2@address.com;
and so on   

我正在寻找匹配并将匹配放在空白文件中的另一个文件看起来像这样 -

12334    email@address.com;
32213    email2@address.com;

我希望它保留数字以及匹配数据。我知道这应该如何工作,但需要知道如何实现它。

我的想法

#!/bin/bash
read -p "enter first file name:" file1
read -p "enter second file name:" file2
FILE_DATA=( $( /bin/cat $file1))
FILE_DATA1=( $( /bin/cat $file2))
for I in $((${#FILE_DATA[@]}))
     do 
     echo $FILE_DATA[$i] | grep $FILE_DATA1[$i] >> output.txt
     done

我希望输出看起来像这样但仅适用于匹配的地址 -

12334 email@address.com;
32213 email2@address.com;

谢谢

4 个答案:

答案 0 :(得分:4)

非常喜欢使用SQL操作文本:

$ cat file1
b@address.com
a@address.com
c@address.com
d@address.com
$ cat file2
10712 e@address.com
11457 b@address.com
19985 f@address.com
22519 d@address.com
$ join -1 1 -2 2 <(sort file1) <(sort -k2 file2) | awk '{print $2,$1}'
11457 b@address.com
22519 d@address.com
  • 对键进行排序(我们在此处使用emails作为键)
  • 加入密钥(file1.column1file2.column2
  • 格式输出(使用awk反转列)

答案 1 :(得分:2)

当您了解到diffcomm时,现在是时候了解unix工具箱中的另一个工具join

Join正如名称所示,它将2个文件连接在一起。您加入的方式基于文件中嵌入的键。

使用连接的第一个限制是数据必须在同一列的两个文件中排序。

file1
a abc
b bcd
c cde

file2
a rec1
b rec2
c rec3


join file1 file2
a abc rec1
b bcd rec2
c cde rec3

您可以参考join手册页,了解如何减少和重新排序输出列。例如

1>join -o 1.1 2.2 file1 file2
a rec1
b rec2
c rec3

您可以使用您的代码输入文件名,将其转换为可推广的脚本。

在for循环中使用管道的解决方案适用于小型数据集,但随着数据大小的增加,为您搜索的每个单词启动新流程的成本将会缩短运行时间。< / p>

我希望这会有所帮助。

答案 2 :(得分:1)

这个awk单行可以帮助你做到这一点 -

awk 'NR==FNR{a[$1]++;next}($2 in a){print $0 > "f3.txt"}' f1.txt f2.txt

NRFNRawk's内置变量,用于存储行号。使用两个文件时,NR不会重置为0。 FNR。因此,当该条件为真时,我们将所有内容添加到数组a。完成first file后,我们会检查second column second file。如果array中存在匹配项,我们会将整行放入文件f3.txt中。如果没有,那么我们忽略它。

使用来自Kev解决方案的数据:

[jaypal:~/Temp] cat f1.txt 
b@address.com
a@address.com
c@address.com
d@address.com
[jaypal:~/Temp] cat f2.txt 
10712 e@address.com
11457 b@address.com
19985 f@address.com
22519 d@address.com
[jaypal:~/Temp] awk 'NR==FNR{a[$1]++;next}($2 in a){print $0 > "f3.txt"}' f1.txt f2.txt 
[jaypal:~/Temp] cat f3.txt 
11457 b@address.com
22519 d@address.com

答案 3 :(得分:1)

通过file1.txt文件读取行并将行分配给var ADDR。 grep file2.txt,内容为var ADDR,并将输出附加到file_result.txt。

(while read ADDR; do grep "${ADDR}" file2.txt >> file_result.txt ) < file1.txt