【问题标题】:using awk to lookup and insert data使用 awk 查找和插入数据
【发布时间】:2015-05-16 06:35:17
【问题描述】:

在我不使用 MS Excel 的持续努力中,我想处理一些数据,将其发送到一个文件,然后使用字段 $1 作为索引将一些记录从一个单独的文件插入到第三个文件中。这可能吗?

我有这样的数据:

2600,foo,stack,1,04/02/2015,ACH Payment,ACH Settled,1500
2600,foo,stack,2,04/06/2015,Credit Card Sale,Settled,100
2600,foo,stack,3,04/07/2015,Credit Card Sale,Settled,157.13
2600,foo,stack,4,04/07/2015,ACH Credit,ACH Settled,.03

我有这个来分组:

cat group.awk
#!/usr/bin/awk -f

BEGIN {
    OFS = FS = ","
}
NR > 1 {
    arr[$1 OFS $2 OFS $3]++
}
END {
    for (key in arr)
        print key, arr[key]
}

小组是这样的:

2600,foo,stack,4

在适用的情况下,对字段 5、6 和 7 应用简单乘法 - 取决于字段 3。

在这个例子中,我们可以说完成的记录是这样的:

2600,foo,stack,4,.2,19.8

现在在一个单独的文件中,我有这些数据:

2600,注册用户,5hPASLJlHlgJR4AQc9sZQ==

基本流程是:

awk -f group.awk data.csv | awk -f math.awk > 完成的.csv

然后使用awk(如果可以的话)在finished.csv中查找字段$1,并在单独的文件(bill.csv)中找到上面的相应记录并打印到第三个文件或插入到bill.csv中。

第三个文件(bill.csv)中的预期输出:

x,y,,1111111,2600,,,,,,,19.8,,,registered user,,,,,,,,,,RS,,,N5hPASLJlHlgJR4AQc9sZQ==,z,a

x,y,,1111111,RS,z,a 将被预填充到我只需要插入三个新记录。

这是 awk 可以完成的事情吗?

编辑

字段 $3 是设置 5、6 和 7 乘法的帐户 ID。

这就是想法:

bill.awk:

NR>1{if($3=="stack" && $4>199) $5=$4*0.03; 
if($3=="stack" && $4<200) $5=$4*0.05
if($3=="user") $5=$4*.01
}1

total.awk:

    awk -F, -v OFS="," 'NR>1{if($3=="stack" && $5<20) $6=20-$5;
if($3=='stack && $5>20) $6=0;}1'

这部分工作正常,最终输出如上:

2600,foo,stack,4,.2,19.8

4*.05 = .2 & 20 - .2 = 19.8

但最低收费是 20 美元

所以我们会纠正它:

4*.05 = .2 & 20 - .2 = 20

额外填充的字段来自一个单独的文件 (bill.csv),我需要在 bill.csv 上的正确记录中填写 20

bill.csv 包含除 20 之外所需的所有内容

之前:

x,y,,1111111,2600,,,,,,,,,,,registered user,,,,,,,,,,RS,,,N5hPASLJlHlgJR4AQc9sZQ==,z,a

之后:

x,y,,1111111,2600,,,,,,,20,,,registered user,,,,,,,,,,RS,,,N5hPASLJlHlgJR4AQc9sZQ==,z,a

这是一个更好的解释吗?继续假设 group.awk、bill.awk 和 total.awk 工作正常。我只需要为字段 $1 提取正确的总计并将其放入 bill.csv 中的正确位置。

【问题讨论】:

  • 您的输入文件有 5 行以 2600,foo,stack 开头,那么为什么您的第一个中间输出以 4 2600,foo,stack,4 结尾?您说Simple multiplication is applied to fields 5, 6 and 7 where applicable--depends on fields 3.,但字段 3 是一个文本字符串 (stack),除非您告诉我们乘法是什么,否则我们无法编写脚本来执行此操作。最终输出 (x,y,,1111111,2600,,,,,,,10.4,,,registered user,,,,,,,,,,RS,,,N5hPASLJlHlgJR4AQc9sZQ==,z,a) 中所有这些额外填充和空字段从哪里来?foo,stack,4 去哪里了?
  • 您输入的第 4 条记录 (2600,foo,stack,404/07/2015,ACH Credit,ACH Settled,.03) 的字段比其他记录少 1 个,对吗? wrt x,y,,1111111,RS,z,a will be pre-populated - 在哪个文件中? I only need to insert three new records - 什么新记录(或者你的意思是新字段)?请清理您的问题以显示 PRECISE、TESTABLE 输入文件以及实际相关的输出和算法。
  • 这里还有一些数据:hastebin.com/alemadadif.nginx
  • 一个好的完成记录看起来像这样:2601,FOS - Las Vegas,stack,468,23.4,0,23.4 我只需要取出 23.4 并将其插入 bill.csv基于 2601。

标签: shell awk sed bsd


【解决方案1】:

也许这是你需要的最后一个 awk。我试图理解你想要什么,我认为这就是合并 awk 的方式:

为了解释:我们首先将文件A保存在一个数组中,其中第一个键作为索引。然后我们搜索文件 B 的每一行,如果 field1 在我们数组的索引之间,如果是,我们将两个文件中的所有数据一起打印

awk -F"," 'BEGIN {while (getline < "record.dat"){ a[$1]=$0; }} {if($1 in a){ print a[$1]","$0}}' file.dat
2600,foo,stack,4,10,10.4,2600,registered user,5hPASLJlHlgJR4AQc9sZQ==

【讨论】:

  • 如果/当 record.dat 由于任何原因无法读取时,它将进入无限循环。不要使用 getline,除非它是一个特定的、适当的应用程序,并且您已阅读并完全理解 awk.info/?tip/getline。该脚本还有其他非 awkishness 问题。
【解决方案2】:

这是您需要的解决方案:

$ cat fileA
2600,foo,stack,1,04/02/2015,ACH Payment,ACH Settled,1500
2600,foo,stack,2,04/06/2015,Credit Card Sale,Settled,100
2600,foo,stack,3,04/07/2015,Credit Card Sale,Settled,157.13
2600,foo,stack,4,04/07/2015,ACH Credit,ACH Settled,.03
2600,foo,stack,5,04/09/2015,ACH Payment,ACH Settled,147.10

$ cat fileB
2600,registered user,5hPASLJlHlgJR4AQc9sZQ==

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR{
    cnts[$1][$2FS$3]++
    next
}
{
    for (val in cnts[$1]) {
        cnt = cnts[$1][val]
        print $1, val, cnt, cnt*2.5, $2, $3
    }
}

$ awk -f tst.awk fileA fileB
2600,foo,stack,5,12.5,registered user,5hPASLJlHlgJR4AQc9sZQ==

但在您更新您的问题之前,我们无法提供比这更具体的帮助。

上面使用 GNU awk 4.* 来处理真正的二维数组。

【讨论】:

  • Bascally 我有一个完整的文件 (file.csv),需要从中取出一条信息,我需要将其放入 bill.csv 中,该文件在 file.csv 中具有匹配字段 $1。这可能吗?
  • 是的,一切皆有可能。您从 2 个名为 group.awkmath.awk 的 awk 脚本开始,但不清楚为什么您有 2 个单独的脚本。名为 data.csvfinished.csv 的 blus 文件。您更新的问题现在还有bill.awktotal.awkbill.csv。这太令人困惑了,以至于我懒得去弄清楚什么是相关的,什么是不相关的。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 2017-11-11
相关资源
最近更新 更多