使用awk处理3个文件


9

考虑以下文件:

file1

boo,8,1024
foo,7,2048

file2

foo,0,24,154
noo,0,10,561

file3

24,154,7,1024,0

我需要转到File1并检查是否$2==7;如果为true,则从File1中获取$1$2$3File1中获取;现在我必须比较$1File1等于$1File2;如果是真的,我不得不采取$3$4文件2,其不存在于文件1,那么我必须去文件3,检查是否$1文件3等于$3文件2,并$2文件3等于$4文件2 ; 如果是,那么我必须检查是否$2来自File1等于$3文件3,那么如果这种情况是真的,我有比较$3File1中$4来自文件3,如果$3文件1大于$4文件3

我尝试了以下脚本:

cat [file1] [file2] [file3] | 
awk -F, 
'{if(NF==3)
    {if($2==7){a[$1]=$1; b[$1]=$2; c[$1]=$3}
    }else
        {if(NF==4){if(a[$1]==$1){d[$3]=$3; e[$4]=$4}
                  }else
                        {if(NF==5){if(d[$1]==$1 && e[$2]==$2){print a[$1], b[$1], c[$1], d[$1]}}
                        }
                  }

  }'

所需的输出是:

foo,7,2048,24,154,1024

Answers:


9

这对我有用:

awk -F, 'FNR==1{++f} \
  f==1 && $2==7 {a1[$1]++; a2[$2]=$3; o=$0} \
  f==2 && a1[$1] {o=o","$3","$4; a3[$3]=$4} \
  f==3 && a3[$1] && $2==a3[$1] && a2[$3] && $4<a2[$3] {print o}' \
file1 file2 file3

说明

  • 第一行(FNR==1{++f})递增文件索引,以便稍后确定我们在1-3中是哪个文件。
  • file1:如果$2相等7
    • 填充数组a1$1作为索引和a2$2作为索引和$3为值
    • o用前3个字段写下变量(输出)
  • 文件2:如果$1file2平等$1file1(prevously写a1
    • 追加$3$4到输出变量o
    • a3$3索引和$4值填充数组。
  • file3:如果:
    • $1等于file2s $3(的索引a3
    • $2等于file2s $4(值a3
    • $3等于file1s $2(的索引a2
    • $4低于file1s $3(值a2
  • 然后:
    • 打印的值o

是否需要反斜杠(最后一个除外)?BEGINFILE(而不是FNR == 1)怎么样?
Archemar

@Archemar BEGINFILE和ENDFILE是gawk扩展名,反斜杠都可以删除,我将其插入,以提高可读性:您可以将整个内容写在一行中,但是看起来不太好
混乱

@chaos,谢谢,但是不幸的是,它总是返回null。
Eng7'9

@ Azizieh7我用mawk和gawk用您的3个输入示例文件对其进行了测试。对我来说,它奏效了。您是否使用其他输入文件或编码/换行符?
混乱

@ chaos,file3中有不同的换行符,但是我使用tr -d'\ 015'来解决这个问题。
2015年

1

TXR解决方案:

@(repeat)
@id,@val0,@val1
@  (next)
@  (skip)
@id,@nil,@val2,@val3
@  (next)
@val2,@val3,@val0,@val4,@val5
@  (require (< (int-str val4) (int-str val1)))
@  (output)
@id,@val0,@val1,@val2,@val3,@val4
@  (end)
@(end)

跑:

$ txr join.txr file1 file2 file3
foo,7,2048,24,154,1024

但是精明的观察者会注意到,在代码的任何地方都没有指定7,只是出现在输出中!这是因为代码实际上正在遍历所有记录,file1打印出所有符合匹配条件和约束条件的组合。样本数据中唯一的一个val07

如果找到更多组合,则可以将其限制为7这样的组合:

$ txr -Dval0=7 join.txr file1 file2 file3
foo,7,2048,24,154,1024

# how about 6?
$ txr -Dval0=6 join.txr file1 file2 file3
# no output

TXR模式提取语言在这里通过重复变量名称,跨多个文件,多行提取模式,非文本约束以及诸如输出之类的嵌入副作用,为隐式向后引用提供了一种大模式匹配。 。

接受的Awk解决方案仔细翻译了TXR Lisp awk

(awk (:begin (set fs "," ofs ","))
     (:let o (a1 (hash :equal-based)) (a2 (hash)) (a3 (hash)))
     (t (mf [orf int-str identity])) ;; map those fields to integers, which can be
     ((and (= arg 1) (= [f 1] 7)) (inc [a1 [f 0] 0])
                                  (set [a2 [f 1]] [f 2])
                                  (set o rec))
     ((and (= arg 2) [a1 [f 0]]) (set o `@o,@[f 2],@[f 3]`)
                                 (set [a3 [f 2]] [f 3]))
     ((and (= arg 3)
           [a3 [f 0]]
           (= [f 1] [a3 [f 0]])
           [a2 [f 2]]
           (< [f 3] [a2 [f 2]])) (prn o)))

跑:

$ txr awkit.tl file1 file2 file3
foo,7,2048,24,154

,1024输出中的必需部分丢失;原始的“ Awk Classic”具有此行为。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.