【问题标题】:awk print line of file2 based on condition of file1awk 根据 file1 的条件打印 file2 的行
【发布时间】:2013-03-04 06:10:51
【问题描述】:

我有两个文件:

猫文件1:

0 xxx
1 yyy
1 zzz
0 aaa

猫文件2:

A bbb
B ccc
C ddd
D eee

如何使用 awk 获得以下输出:

B ccc
C ddd

我的问题是,如何仅当 file1 中的某个字段(即字段 1)与某个值(即 1)匹配时才从 file2 打印行?

附加信息:

文件 file1 和 file2 的行数相等。

文件file1和file2有几百万行,无法读入内存。

file1 有 4 列。

file2 大约有 1000 列。

【问题讨论】:

    标签: awk


    【解决方案1】:

    尝试这样做(有点混淆):

    awk 'NR==FNR{a[NR]=$1}NR!=FNR&&a[FNR]' file1 file2
    

    在多行上它可以更清晰(提醒,awk 的工作方式如下:condition{action}

    awk '
        NR==FNR{arr[NR]=$1}
        NR!=FNR && arr[FNR] 
    ' file1 file2
    

    如果我删除 sn-p 的“聪明”部分:

    awk '
        if (NR == FNR) {arr[NR]=$1}
        if (NR != FNR && arr[FNR]) {print $0} 
    ' file1 file2
    

    awk 单独找到一个条件(无操作),如NR!=FNR && arr[FNR],默认情况下打印在STDOUT 上,隐含表达式为TRUE (> 0)

    说明

    • NR 是当前记录从输入开始的编号
    • FNR当前文件中当前记录的序号(所以NR 与第二个文件中的FNR 不同)
    • arr[NR]=$1 :以当前NR 的索引为第一列提供数组arr
    • 如果NR!=FNR我们在下一个文件中并且如果数组的值是1,那么我们打印

    【讨论】:

    • 它适用于我指定的输入。但是,我在 file1 和 file2 中有多个字段。我将编辑我的问题。
    • 帖子已相应编辑并附有解释,不需要的print 已被删除
    • 确实如此。谢谢你。今天晚些时候我会接受答案。感谢您也提供解释!
    • 我实际上不能使用你的方法。它需要太多的内存。我必须使用 wau 提供的解决方案。
    【解决方案2】:

    没有 awk 解决方案那么干净

    $ paste file2 file1 | sed '/0/d' | cut -f1
    B
    C
    

    您提到了有关数百万行的内容,为了只通过文件一次,我会求助于 python。可能是这样的(python 2.7):

    with open("file1") as fd1, open("file2") as fd2:
        for l1, l2 in zip(fd1, fd2):
            if not l1.startswith('0'):
                print l2.strip()
    

    【讨论】:

    • Python 绝对是一个选择(如果 sputnick 没有为我提供 awk 解决方案,我打算使用它)。感谢您的建议。
    • 我最终使用了您的粘贴解决方案,它使用的内存不到 20MB,运行时间不到 30 秒。我做了:粘贴file1 file2 | awk '{if($1==1) 打印}' |剪切-f2
    • @tommy.carstensen - 很好,很高兴我能帮上忙。
    【解决方案3】:
    awk '{
      getline value <"file2";
      if ($1)
        print value;
    }' file1
    

    【讨论】:

    • 我得到一个语法错误:awk: {getline value
    • 如果都是一行,必须在getline命令后加分号(我更新了代码添加)
    • 您的解决方案同样有效。我会测试它们(你的和 sputnick 的),看看哪个更快。
    • 当我使用这种方法时,我也超过了我的 100MB 内存阈值。看来我将不得不求助于 Python。
    猜你喜欢
    • 1970-01-01
    • 2014-08-14
    • 2017-07-10
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 2020-10-29
    相关资源
    最近更新 更多