【问题标题】:extracting data from two list using a shell script使用 shell 脚本从两个列表中提取数据
【发布时间】:2011-12-22 01:54:41
【问题描述】:

我正在尝试创建一个 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;

谢谢

【问题讨论】:

    标签: linux bash shell


    【解决方案1】:

    很像使用 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.column1, file2.column2)
    • 格式化输出(使用awk反转列)

    【讨论】:

      【解决方案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 循环中使用管道的解决方案适用于少量数据,但随着数据量的增长,为您要搜索的每个单词启动一个新进程的成本将拖累运行时间。

      我希望这会有所帮助。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          这个awk one-liner 可以帮你做到这一点 -

          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 filesecond column。如果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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-06-14
            • 2011-10-14
            • 2010-12-08
            • 2020-06-18
            • 2020-09-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多