【问题标题】:compare 2 fixed length flat files based on fields in unix根据 unix 中的字段比较 2 个固定长度的平面文件
【发布时间】:2014-02-17 04:03:23
【问题描述】:

我是 unix 新手,需要合并两个固定长度的平面文件,并且有共同的 记录是事务 id 和批次编号。

在 file1.txt 中,事务 id 是从 1 到 10,批次 id 是从 19 到 21。 在 file2.txt 中,事务 id 是从 12 到 21,批处理 id 是从 30 到 32。

对于两个文件中匹配的行/记录,从 file2.txt 中剪切/复制发票编号,并将其最后附加到 file1.txt 中。发票编号与我的 trans id 和批号不在同一行。

请有人帮忙。

* 示例输入 - File1.txt *

161065730303122012098
161065846403042011784
161065916903012012431
161066813503042019678
161066835008092012136
161067040701122012984
161067106602122010267

* 示例输入 - File2.txt *

2.60E5-2670161065730303122012098
userid 234
date03122012
Invnum987678
2.60E5-2670161065846403042011098
userid 871
date03122012
Invnum987912
2.60E5-2670161065916903012012075
userid 871
date031610671066122012
Invnum987654
2.60E5-2670161066813503042011075
userid 871
date03122012
Invnum987322
2.60E5-2670161066835008092012075
userid 871
date03122012
Invnum987323
2.60E5-2670161067040701122012075
userid 871
date03122012
Invnum987324
2.60E5-2670161067106602122010074
userid 811
date03122012
Invnum987325

期望的输出

161065730303122012098987678
161065846403042011784987912
161065916903012012431987654
161066813503042019678987322
161066835008092012136987323
161067040701122012984987324
161067106602122010267987325

【问题讨论】:

  • When you tried doing this yourself,您遇到问题的哪一部分?如果您分享您的代码,我们或许可以帮助您修复它。
  • @Johnsyweb,我还没有编写任何代码。我正在尝试构建 loigc,然后将其转换为代码。
  • 所需输出中的第 4 行 161066813503042019678987322 怎么样?对我来说它是可疑的..
  • @Awk,有什么值得怀疑的?你是说日期的错别字吗?
  • 您对161066813503042019678987322 的期望如何,正如您在所需输出中提到的那样......您是否尝试过下面发布的代码?

标签: shell unix awk


【解决方案1】:

试试这样的:

awk -F"-" '
NR==FNR && NF>1 {
    v=substr($2,5,18);
    next
}
NR==FNR && /Invnum/ {
    sub(/Invnum/,"",$0);
    a[v]=$0;
    next
}
(substr($0,1,18) in a) {
    print $0 a[substr($0,1,18)]
}' file2.txt file1.txt

输出:

161065730303122012098987678
161065846403042011784987912
161065916903012012431987654
161066835008092012136987323
161067040701122012984987324
161067106602122010267987325

【讨论】:

    【解决方案2】:
    awk 'FNR==NR {
                  if(length($0)==32)
                  p = substr($0,12,18)
                  if(/Invnum.*/)
                  A[p]=substr($0,7)
                  next
                 }
    ((s=substr($1,1,18)) in A){ print $1 A[s] }' file2 file1.txt
    

    --编辑---

    一个班轮

    $ awk 'FNR==NR {if(length($0)==32)p = substr($0,12,18);if(/Invnum.*/)A[p]=substr($0,7);next}((s=substr($1,1,18)) in A){ print $1 A[s] }' file2 file1.txt
    

    【讨论】:

    • 感谢您的回复。恐怕如果我的行不以“2.60E5”开头,这将不起作用。
    • 好的,把if(/2\.60E5-.*/)改成if(/-.*/)或者if(length($0)==32)就可以了。
    • 我按原样运行,下面是输出。发票编号重复且未提取正确的发票编号。我可能需要在这里调整一些东西。 161065730303122012098987654 161065846403042011784987654 161065916903012012431987654 161066813503042019678987325 161066835008092012136987325 161067040701122012984987325 161067106602122010267987325 跨度>
    • 谢谢 Awk。一个班轮很棒。我实际上想在 file2 中查找 2 个字段(trnx id 和批处理 id)并生成输出。
    • @Awk 为什么要添加0
    【解决方案3】:

    我用过文件 a.txt 和 b.txt

    for i in `cat b.txt`; do; a=$(echo $i|cut -c1-10); echo $(grep $a a.txt|cut -c12-)$(grep -A3 $a a.txt|tail -n1|cut -c7-) ;done
    161065730303122012098987678
    161065846403042011098987912
    161065916903012012075987654
    161066813503042011075987322
    161066835008092012075987323
    161067040701122012075987324
    161067106602122010074987325
    

    这样好吗?

    【讨论】:

    • 谢谢。这个有效,但是我想查找 2 个字段。我在 file1 中有 trxn id 和 batchid,不确定在哪里放置批处理 id。我尝试了几件事,但没有奏效。
    猜你喜欢
    • 2019-08-09
    • 2011-01-25
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 2021-09-17
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多