基于文件1的条件,打印文件2的行(使用awk)

3

I have two files:

cat file1:

0 xxx
1 yyy
1 zzz
0 aaa

查看文件2的内容:

A bbb
B ccc
C ddd
D eee

How do I get the following output using awk:

B ccc
C ddd

我的问题是,如果文件1中的某个字段(例如字段1)匹配特定值(例如1),如何仅打印文件2中的行?

额外信息:

文件file1和file2有相等数量的行。

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

file1有4列。

file2大约有1000列。

3个回答

3

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

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

在多行上,可能更清晰 (提醒一下,awk的工作方式是这样的:条件{动作}):

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

如果我去掉这个代码片段中“聪明”的部分:
awk '
    if (NR == FNR) {arr[NR]=$1}
    if (NR != FNR && arr[FNR]) {print $0} 
' file1 file2

awk 发现一个条件独立存在而没有动作执行时,例如 NR!=FNR && arr[FNR],它默认在 STDOUT 上隐式输出结果,前提条件是这个表达式为真(>0)。
解释:
- NR 是从输入开始算起当前记录的编号 - FNR 是当前文件中当前记录的顺序编号(所以第二个文件中 NR 不同于 FNR) - arr[NR]=$1:将当前 NR 的索引和第一列存入数组 arr - 如果 NR!=FNR 说明已经到了下一个文件,如果数组的值为 1,则进行打印。

它在我指定的输入上运行良好。但是,我的file1和file2中有多个字段。我将编辑我的问题。 - tommy.carstensen
帖子已编辑,根据说明进行了修改,并删除了不必要的“print”。 - Gilles Quénot
确实是这样。谢谢。我会在今天晚些时候接受这个答案。还要感谢您提供了解释! - tommy.carstensen
我实际上不能使用你的方法。它需要太多的内存。我必须采用wau提供的解决方案。 - tommy.carstensen

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解决方案,我打算使用它)。感谢您的建议。 - tommy.carstensen
我最终使用了您的粘贴解决方案,它使用不到20MB的内存,在不到30秒的时间内运行。我的操作是:将file1和file2粘贴在一起,然后使用awk命令筛选出第一列为1的行,并使用cut命令提取第二列。 - tommy.carstensen
@tommy.carstensen - 很好,很高兴我能帮到你。 - Fredrik Pihl

2
awk '{
  getline value <"file2";
  if ($1)
    print value;
}' file1

我遇到了一个语法错误: awk: {getline value <"file2" if ($1) print value;} awk: ^ 语法错误 - tommy.carstensen
如果所有内容都在一行上,则必须在getline命令之后添加分号(我更新了代码以添加它)。 - wau
你的解决方案也可以。我会测试两个(你的和sputnick的),看哪一个更快。 - tommy.carstensen
当我使用这种方法时,我的内存超过了100MB的阈值。看来我不得不求助于Python。 - tommy.carstensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接