使用命令行实用程序执行以下映射更新

时间:2015-06-17 17:36:20

标签: shell command-line awk terminal

我是使用命令行实用程序的完全新手,我想知道如何处理如下信息:

mapping.txt

80  001 002
81  011 012 013 014
82  021 022
...

input.txt

81  103823044
80  103823054
81  103823064
...

所需output.txt

103823044|011|
103823044|012|
103823044|013|
103823044|014|
103823054|001|
103823054|002|
103823064|011|
103823064|012|
103823064|013|
103823064|014|

我做了简单的映射,其中列号是固定的,但我不确定如何将动态列数映射到所需的输出

2 个答案:

答案 0 :(得分:2)

如果订单不重要,加入和awk可以轻松完成工作。

{{1}}

答案 1 :(得分:1)

这是一个使用多维数组做你想做的GNU awk脚本:

#!/usr/bin/awk -f

BEGIN { OFS="|" }

FNR==NR { for(i=2;i<=NF;i++) a[$1][$i]; next }

$1 in a { for(k in a[$1]) print $2, k, "" }

如果将其保存到script.awk然后chmod +x script.awk这样的文件中,则可以将其保存为:

$ ./script.awk mapping.txt input.txt
103823044|011|
103823044|012|
103823044|013|
103823044|014|
103823054|002|
103823054|001|
103823064|011|
103823064|012|
103823064|013|
103823064|014|

这是剧本的细分:

  • BEGIN - 将输出字段分隔符设置为|
  • FNR==NR - 处理第一个文件(mapping.txt)并首先通过$1将数据存储在多维数组中,然后存储到其他字段中。 next跳过任何其他行处理。
  • $1 in a - 测试一下该行是否有映射。如果是这样,请按顺序打印相应的映射(也是GNU awk)。 print命令中的逗号将转换为OFS值。

它可以重新制作一个&#34; one-liner&#34;像:

awk -v OFS="|" 'FNR==NR {for(i=2;i<=NF;i++) a[$1][$i]; next} $1 in a {for(k in a[$1]) print $2, k, ""}' mapping.txt input.txt

这是脚本的一个版本,它使用一维数组存储$0,然后split()以保存顺序:

#!/usr/bin/awk -f

BEGIN { OFS="|" }

FNR==NR { a[$1]=$0; next }

$1 in a { c=split(a[$1], b); for(i=2;i<=c;i++) print $2, b[i], "" }