【问题标题】:Grep csv with arguments from another csv使用来自另一个 csv 的参数的 Grep csv
【发布时间】:2018-04-08 05:17:57
【问题描述】:

如果我在 file1.csv 中有以下内容(空格分隔):

RED 4 VWX
BLUE 2 MNO
BLUE 7 DEF
PURPLE 6 JKL
BLACK 8 VWX
BROWN 1 MNO
RED 1 GHI
RED 7 ABC

file2.csv 中的以下内容(逗号分隔):

BROWN,2
RED,5
YELLOW,8

有没有办法使用 file2.csv 在 file1.csv 中搜索匹配的行?目前,如果我想使用 file2.csv 中的第 1 行术语来搜索 file1.csv,我必须手动输入以下内容:

grep "BROWN" file1.csv | grep "2"

我想自动执行此搜索以查找 file1.csv 中与 file2.csv 中给定行中的两个项目匹配的行。我已经尝试了一些 awk 命令,但是很难在 grep 中使用 awk 输出作为参数。我正在通过标准的 Mac 终端运行所有这些(所以我想我正在使用 bash?)非常感谢任何帮助。谢谢!

【问题讨论】:

  • 您不需要使用awk 输出作为grep 的参数。也可以使用awk 进行匹配。

标签: linux bash csv awk grep


【解决方案1】:

awk单行

awk 'FNR==NR{a[$1]=$2; next} ($1 in a) && a[$1]==$2' FS=, file2.csv FS=" " file1.csv

FNR==NR{a[$1]=$2; next}:要读取第一个输入文件,此处为file2.csv,并创建一个关联数组a,其中键为file2.csv 中的第1 列,值为item number

($1 in a) && a[$1]==$2:在迭代第二个输入文件时,即file1.csv,检查第 1 列值是否作为数组 a 中的键存在。如果存在,请检查 item number 是否匹配。如果匹配,结果将为1,并打印行。

或者

只需使用 grep

grep -wf <(tr "," " " <file2) file1

在这里,我们使用tr 将file2 中的, 替换为空格,并使用file2 中的每一行作为在file1 中搜索的模式,使用我们可爱的grep 提供的-f 选项

-w 是匹配单词边界,这样ABC 1 就不会匹配ABC 123

【讨论】:

  • 你真的可以这样改变FS吗?整洁!
  • 如果 file2.csv 包含 A 1 并且 file1.csv 包含 A 12,则 grep 方法将给出错误匹配
  • @Barmar:感谢您的第一条评论。其次,我使用 -w 选项更新了 grep 解决方案。
  • 出于某种原因,在尝试每个单行时,我没有得到任何输出。结果不应该打印在下面吗?
  • @DanielEsporma:哈哈,是的,结果应该在这个命令的下方。这很可爱 :P 你确定你给文件的顺序是正确的。以逗号分隔的一个将首先出现,然后另一个作为 file1.csv。您提供的输入也没有匹配的记录。
【解决方案2】:

您可以使用awk 进行匹配。

awk 'BEGIN { FS=","; }
     NR == FNR { a[$1,$2]++; next; }
     FNR == 1 { FS=" "; }
     ($1,$2) in a' file2.csv file1.csv

第二行创建一个数组,其键是file2.csv 中的值。当我们处理 file1.csv 时,第三行将字段分隔符更改为空格,最后一行匹配前两个字段是数组中键的任何行。

【讨论】:

  • 您可以使用FNR==1 {FS=" "},这样您就不需要为第二个文件的每一行更改FS
  • 跟进蝙蝠侠的评论,($1 FS $2) in a
  • 抱歉这个荒谬的问题,但是如何在终端中输入 4 行命令?我应该把它做成一个脚本并从那里运行它吗?
  • 只需键入 4 行。由于未闭合的引号,shell 知道它没有完成。
  • 你也可以把awk的代码放到一个文件里,用awk -f filename file2.csv file1.csv
猜你喜欢
  • 2020-08-18
  • 1970-01-01
  • 2012-12-26
  • 2019-12-10
  • 2011-04-07
  • 2021-07-08
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多