【问题标题】:Merge files with awk使用 awk 合并文件
【发布时间】:2021-09-07 19:53:34
【问题描述】:

我试图合并file1file2,基于file2 中column2 中的数字和file1 中column1 中的数字,主要由逗号分隔。在file2中我要匹配的数字之间还有一个.分隔符

这是文件 1。

1,Mary,24 Fuller Rd
2,Fred,19 St Johns
3,Jonathan,8 Poplar Drive
4,Susan,116 Shepherds Way
5,Michael,4 Nerthern Court

和文件 2

Dawning,Order.5.DHL
Hawkins,Order.3.FedEx
Jacob,Order.2.Yodel
Plateu,Order.4.DPD
Martins,Order.1.Hermes

我的方法是从file2split 中提取密钥。作为单个文件,这是可行的,但是在处理多个文件时,行为很奇怪,而不是预期的结果。

awk -F, '{{split($2,i,".")}{ print i[2]}' file2
5
3
2
4
1
awk -F, 'NR==FNR{split($2,i,"."); next}{ print i[2]}' file2 file1
1
1
1
1
1

如果我删除split,我只会得到预期的结果,但无法提取匹配项。

awk -F, 'NR==FNR{array[$2]}END{ for (i in array) print i}' file2 file1
Order.4.DPD
Order.3.FedEx
Order.1.Hermes
Order.5.DHL
Order.2.Yodel

我已经采取了许多其他步骤但都失败了,但这可能会使问题过于臃肿,因此如果需要有关此方面的更多信息,请询问。

我的预期结果是这样的

Mary Martins 24 Fuller Rd
Fred Jacob 19 St Johns
Jonathan Hawkins 8 Poplar Drive
Susan Plateu 116 Shepherds Way
Michael Dawning 4 Nerthern Court

其中file2 中的column2 和file1 中的column1 基于数字匹配,因此打印file1 中的$2$NFfile2 中的$1

这是我在众多尝试中失败的一些尝试

awk -F, 'NR==FNR {M=$1; array[$2]; next}{($1 in array)}END{ for (i in array) print $2, M, $NF}' file2 file1
awk -F, 'NR==FNR {M=$1; array[$2]; for (i in array) split(i,a,"."); next} $1==a[2]{print $2,M, $3}' file2 file1
awk -F, 'NR==FNR {M=$1; array[$2]; next}END { for (i in array) split(i,a,".")}($1~a[2]){ print $2,M}' file2 file1

我已经包含了perl 标签,因为我对perl 的解决方案很感兴趣,但如果可能的话,我主要想用awk 做到这一点。

谢谢。

【问题讨论】:

  • 请注意,file1 和您的预期输出与第一行不匹配,可能是拼写错误Fuller Road?此外,最好将输入和预期输出组合在一起,而不是需要太多滚动来理解问题。

标签: awk


【解决方案1】:
$ awk -F'[.,]' 'NR==FNR{a[$3]=$1; next} {print $2, a[$1], $3}' file2 FS=, file1
Mary Martins 24 Fuller Road
Fred Jacob 19 St Johns
Jonathan Hawkins 8 Poplar Drive
Susan Plateu 116 Shepherds Way
Michael Dawning 4 Nerthern Court
  • -F'[.,]' 使用 ., 作为 file2 的字段分隔符
  • NR==FNR{a[$3]=$1; next} 根据第三个字段保存file2 的第一个字段作为键
  • 参数列表中file1 之前的FS=, 将字段分隔符更改为, for file1
  • print $2, a[$1], $3 打印所需数据(默认OFS 为单个空格字符)

【讨论】:

    【解决方案2】:
    perl -F'[.,]' -ane '$ARGV eq "file2" ? $r{$F[2]} = $F[0] : print "$F[1] $r{$F[0]} $F[2]"' file2 file1
    
    • -F'[.,]' 使用 ., 作为 file2file1 的字段分隔符
    • file2, $F[0] = , $F[2] = 我们想与file1 id关联的id
    • file1$F[0] = id$F[1] = 名字$F[2] = 地址
    • -ane 用于在命令行的给定文件中循环/迭代行并将$_ 自动拆分为@F
    • 这个例子在 Perl 中使用三元运算符,看起来像 CONDITION ? EVALUATE_IF_CONDITION_WAS_TRUE : EVALUATE_IF_CONDITION_WAS_FALSE
    • $ARGV读行时包含当前文件名
    • $ARGV eq "file2" - 这是条件
    • 如果从"file2" 读取的行为真,那么我们将id 作为键,将姓作为值存储到Perl 哈希($r)
    • 一旦在file2 上完成该行,条件将为假,因为$ARGV 将是'file1'
    • 因为我们在$r 中已经有了file2 映射,所以我们可以使用$r{$F[0]} 获取姓氏

    【讨论】:

    • 你可以试试旧版 perl 的 -ane 选项
    猜你喜欢
    • 2014-07-02
    • 2018-12-11
    • 2015-02-20
    • 1970-01-01
    • 2016-07-30
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    相关资源
    最近更新 更多