【问题标题】:Shell script - copy lines from file by keyShell 脚本 - 按键从文件中复制行
【发布时间】:2013-01-24 21:08:59
【问题描述】:

我有两个输入文件:

file1
123
456
789

file2
123|foo
456|bar
999|baz

我需要从file2中复制key在file1中的行,所以最终结果是:

file3
123|foo
456|bar

现在,我正在使用一个 shell 脚本,它遍历它们的密钥文件并为每个密钥文件使用 grep:

grep "^${keys[$keyindex]}|" $datafile >&4

但正如您可以想象的那样,这非常慢。密钥文件 (file1) 有大约 400,000 个密钥,数据文件 (file2) 有大约 750,000 行。有没有更好的方法来做到这一点?

【问题讨论】:

  • 你为什么使用 shell 脚本?
  • 在更大的脚本中,在此之前发生的许多其他步骤。我希望不需要维护两个不同的东西。
  • 我从未尝试过,但我认为您可以将 python 代码嵌入到多行 bash 字符串中,然后直接将其发送到 python 解释器,而无需单独的文件。

标签: bash shell grep


【解决方案1】:

你可以试试join

join -t'|' file1.txt file2.txt > file3.txt

【讨论】:

    【解决方案2】:

    我会使用 Python 之类的东西,如果您使用像 set 这样的优化数据类型,它的处理速度会非常快。不确定您的确切要求,因此您需要进行相应调整。

    #!/usr/bin/python
    
    # Create a set to store all of the items in file1
    Set1 = set()
    for line in open('file1', 'r'):
       Set1.add(line.strip())
    
    # Open a file to write to
    file4 = open('file4', 'w')
    
    # Loop over file2, and only write out the items found in Set1
    for line in open('file2', 'r'):
       if '|' not in line: 
          continue
    
       parts = line.strip().split('|', 1)
       if parts[0] in Set1:
           file4.write(parts[1] + "\n")
    

    【讨论】:

      【解决方案3】:

      join 是最好的解决方案,如果排序没问题的话。一个 awk 解决方案:

      awk -F \| '
          FILENAME==ARGV[1] {key[$1];next} 
          $1 in key
      ' file1 file2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        相关资源
        最近更新 更多