按列连接两个变量,并使用默认值

时间:2017-04-06 08:35:48

标签: bash awk

我希望逐列连接两个变量,同时用一些默认值填充空白行。

echo var1
location|Serial
001|0
003|1
007|0
009|1

echo var2
name|location|type|built
name1|001|type1|2009
name2|003|type4|2012
name3|007|type1|2010
name4|009|type2|2015
name5|002|type0|2016

我设法打印以下内容:

 paste <(echo "$var2"|awk 'BEGIN{print "name","location","type","built","serial"} NR>1') <(echo "$var1"|awk -F'|' 'NR>1{$1=$1;print FS $2}')
name location type built serial |0
name1|001|type1|2009    |1
name2|003|type4|2012    |0
name3|007|type1|2010    |1
name4|009|type2|2015
name5|002|type0|2016

期望的输出:

name|location|type|built|serial
name1|001|type1|2009|0
name2|003|type4|2012|1
name3|007|type1|2010|0
name4|009|type2|2015|1
name5|002|type0|2016|NA

3 个答案:

答案 0 :(得分:3)

试试这个 -

 awk 'BEGIN{FS=OFS="|"} NR==FNR{a[$1]=$2;next} {print (a[$2]!=""?$0 OFS a[$2] : $0 OFS "NA")}' <(echo "$var1") <(echo "$var2")
name|location|type|built|Serial
name1|001|type1|2009|0
name2|003|type4|2012|1
name3|007|type1|2010|0
name4|009|type2|2015|1
name5|002|type0|2016|NA
  

解释 -

     

打印(a [$ 2]!=“”?$ 0 OFS a [$ 2]:$ 0 OFS“NA”作为左外   加入,如果没有找到第5列的值,它将被替换为   “NA”

答案 1 :(得分:3)

awk 'BEGIN{ 
            FS=OFS="|"                         # set i/p and o/p field separator
     }
     FNR==NR{                                  # Here we read contents from first arg
               a[$1]=$2;                       # populate array a where index being field1 and value being field2
               next                            # stop processing go to next line
     }
     {                                         # Here we read second arg
        print $0,($2 in a) ? a[$2] : "NA"      # if array a has index that is field2 value of 2nd file/var then serial no else NA 
     }' <(echo "$var1") <(echo "$var2")

由于您的输入是可变的而不是文件,因此您可以执行以下操作

定义变量

$ read -d -r var1 <<EOF                                                             
location|Serial
001|0
003|1
007|0
009|1
EOF

$ read -d -r var2 <<EOF 
name|location|type|built
name1|001|type1|2009
name2|003|type4|2012
name3|007|type1|2010
name4|009|type2|2015
name5|002|type0|2016
EOF  

变量的内容

$ echo "$var1"
location|Serial
001|0
003|1
007|0
009|1

$ echo "$var2"
name|location|type|built
name1|001|type1|2009
name2|003|type4|2012
name3|007|type1|2010
name4|009|type2|2015
name5|002|type0|2016

<强>输出

$ awk 'BEGIN{FS=OFS="|"}FNR==NR{a[$1]=$2;next}{print $0,($2 in a)?a[$2]:"NA"}' <(echo "$var1") <(echo "$var2")
name|location|type|built|Serial
name1|001|type1|2009|0
name2|003|type4|2012|1
name3|007|type1|2010|0
name4|009|type2|2015|1
name5|002|type0|2016|NA

阅读内置

  

-d DELIM DELIM的第一个字符用于终止输入   线,而不是新线。

     

-r如果给出此选项,则反斜杠不会作为转义   字符。反斜杠被认为是该行的一部分。在   特别是,反斜杠 - 换行符对不能用作一行   延续。

答案 2 :(得分:1)

不需要awk:

$scope.save = function() {
   //connect with backend
}).success(function(data, status) {
     alert('Successfully Saved');
  })
  .error(function(error) {
     console.log($scope.status);
  });
}

输出:

paste -d'|' <(<<<"$var2") <(<<<"$var1") | cut --complement -d'|' -f5

你究竟在问什么?

您希望基于var1中的字段1和var2中的字段2加入输入。在这种情况下,我建议使用coreutils中的name|location|type|built|Serial name1|001|type1|2009|0 name2|003|type4|2012|1 name3|007|type1|2010|0 name4|009|type2|2015|1 name5|002|type0|2016 ,它直接支持这一点,例如:

join

输出:

join -t '|' -11 -22 -o'2.1 2.2 2.3 2.4 1.2' -a2 -eNA <(<<<"$var1") <(<<<"$var2")