另一个 awk(ward) 问题 - 使用多键映射子字符串

另一个 awk(ward) 问题 - 使用多键映射子字符串

我有两个如下所示的文件:

mapping.txt:

100178  L08/2015
100180  L08/2015
103822  J03/2012
103823  A06/2012
103823  J02/2012
103823  J03/2012
...

input.txt:

100180011|225|
100180011|226|
100181111|201|
100181111|202|
103823004|011|
103823004|012|
...

output.txt如果输入文件的前 6 位数字与映射文件中的一个或多个条目匹配,则输出第三列作为映射文件的第二列,否则输入“B00/0000” :

100180011|225|L08/2015
100180011|226|L08/2015  
100181111|201|B00/0000
100181111|202|B00/0000
103823004|011|A06/2012
103823004|011|J02/2012
103823004|011|J03/2012
103823004|012|A06/2012
103823004|012|J02/2012
103823004|012|J03/2012

理想情况下,这应该可以在 OSX 上运行,但我也可以访问 Linux 机器。

答案1

假设bash,并且还假设两个文件都已排序:

join -a1 <(sed 's/./& /6' input.txt) mapping.txt | sed 's/ //g; s/|$/|B00\/0000/'

输出:

100180011|225|L08/2015
100180011|226|L08/2015
100181111|201|B00/0000
100181111|202|B00/0000
103823004|011|A06/2012
103823004|011|J02/2012
103823004|011|J03/2012
103823004|012|A06/2012
103823004|012|J02/2012
103823004|012|J03/2012

awk看不到,抱歉。 :)

编辑:解释:

  • sed 's/./& /6'- 在每行的第 6 个字符后添加一个空格,因此输出为100180 011|225|L08/2015
  • join -a1连接第一列上的文件;-a1告诉join保留第一个文件中不匹配的行不变
  • sed 's/ //g;'- 删除结果中的空格
  • ... 's/|$/|B00\/0000/'- 添加/|B00/0000到以 结尾的行|,即添加到第一个文件中不匹配的行。

答案2

您可以尝试以下操作awk

awk 'NR == FNR { k = substr($1, 1, 6); x[$1,$2] = k; y[$1,$2] = 0; next; } { for (i in x) { if (x[i] == $1) { split(i, t, SUBSEP); print t[1] "|" t[2] "|" $2; y[i] = 1; } } } END { for (i in y) if (y[i] == 0) { split(i, t, SUBSEP); print t[1] "|" t[2] "|B00/0000" } }' FS="|" input.txt FS=" " mapping.txt

结果应该是:

100180011|225|L08/2015
100180011|226|L08/2015
103823004|011|A06/2012
103823004|012|A06/2012
103823004|011|J02/2012
103823004|012|J02/2012
103823004|011|J03/2012
103823004|012|J03/2012
100181111|201|B00/0000
100181111|202|B00/0000

相关内容