根据bash中的前三列加入两个变量

时间:2017-04-26 06:37:01

标签: bash awk

我需要根据前三列的值加入两个变量,我已经尝试了this Question但是我无法弄清楚解决方案,因为我无法理解解决方案是如何实现的,所以不能用新的数据集调整解决方案。

x='AA   N-1 0   OPEN    WORKING REACHABLE
AA  N-1 0   OPEN    WORKING REACHABLE
AA  N-1 0   OPEN    WORKING REACHABLE
BB  N-1 0   OPEN    WORKING REACHABLE
BB  N-1 0   OPEN    WORKING REACHABLE
CC  N-1 0   OPEN    WORKING REACHABLE
DD  N-1 0   OPEN    WORKING REACHABLE'


y='AA   N-1 0   XYZ-0   PINGABLE
AA  N-1 0   XYZ-1   PINGABLE
AA  N-1 0   XYZ-2   PINGABLE
CC  N-1 0   IJK-0   NOT-PINGABLE'

我试过了:

awk 'NR==FNR{a[$1,$3]=$4; next}{$7="NA";if(($1,$3) in a){$7=a[$1,$3]} print}' <(echo "$x"|sort)  <(echo "$y"|sort)

   echo "$x" |while read name node location lastThree;
    do
        siLastTwo=$(echo "$y" |awk '{print $4,$5}')
        echo "$y"|awk '{NF=3}1' |grep -q  "$name $node $location" ;
            if [ $? -eq 0 ];then
                echo "$name $node $location $lastThree $siLastTwo"
            else
                echo "$name $node $location NA NA"
            fi
    done |awk 'NF==8'|column -t

我需要实现这样的目标:

AA  N-1 0   OPEN    WORKING REACHABLE   XYZ-0   PINGABLE
AA  N-1 0   OPEN    WORKING REACHABLE   XYZ-1   PINGABLE
AA  N-1 0   OPEN    WORKING REACHABLE   XYZ-2   PINGABLE
BB  N-1 0   OPEN    WORKING REACHABLE   NA      NA
BB  N-1 0   OPEN    WORKING REACHABLE   NA      NA
CC  N-1 0   OPEN    WORKING REACHABLE   IJK-0   NOT-PINGABLE    
DD  N-1 0   OPEN    WORKING REACHABLE   NA      NA

谦虚的请求:请帮助我,不仅仅是解决方案,还有一些解释,因为我知道我不应该继续问类似的问题。谢谢。

3 个答案:

答案 0 :(得分:1)

首先,请原谅我这个代码。我相信它很丑陋,但它的工作(除了NA列,但我希望你能快速解决它)。

echo "${x}" | while read line; do
col1="$(echo "${line}" | awk '{print $1}')"
col2="$(echo "${line}" | awk '{print $2}')"
col3="$(echo "${line}" | awk '{print $3}')"
#echo "col1: ${col1}, col2: ${col2}, col3: ${col3}"
#echo "===show matched for line: '${line}'====="
matcher="$(echo "${y}" | awk -v col1="${col1}" -v col2="${col2}" -v col3="${col3}" '($1 == col1) && ($2 == col2) && ($3 == col3) {$1=$2=$3=""; print}')"
#echo "${matcher}"
if [ -n "${matcher}" ]; then
    echo "${matcher}" | while read mtch; do
        res="${line}${mtch}"
        echo ${res}
    done
else
    echo ${line}
fi
done

答案 1 :(得分:0)

使用正则表达式迭代所有行和匹配

x=('AA   N-1 0   OPEN    WORKING REACHABLE'
'AA  N-1 0   OPEN    WORKING REACHABLE'
'AA  N-1 0   OPEN    WORKING REACHABLE'
'BB  N-1 0   OPEN    WORKING REACHABLE'
'BB  N-1 0   OPEN    WORKING REACHABLE'
'CC  N-1 0   OPEN    WORKING REACHABLE'
'DD  N-1 0   OPEN    WORKING REACHABLE')


y=('AA   N-1 0   XYZ-0   PINGABLE'
'AA  N-1 0   XYZ-1   PINGABLE'
'AA  N-1 0   XYZ-2   PINGABLE'
'CC  N-1 0   IJK-0   NOT-PINGABLE')

filter='(\w{2}\s+\S{3}\s+\w)\s+(.*)'

if [ ! -z output.log ]; then
    rm output.log
fi

touch output.log

for ((i = 0; i < ${#x[@]}; i++)) do
    x_a=${x[$i]}

    y_matched=0

    for ((j = 0 ; j < ${#y[@]}; j++ )) do
        y_a=${y[$j]}

        if [[ $x_a =~ $filter ]]; then
            x_prefix=${BASH_REMATCH[1]}
            x_suffix=${BASH_REMATCH[2]}

            if [[ $y_a =~ $filter ]]; then

                y_prefix=${BASH_REMATCH[1]}    
                y_suffix=${BASH_REMATCH[2]}

                if [[ $x_prefix == $y_prefix ]] ; then
                    if ! grep "$x_prefix $x_suffix $y_suffix" output.log > /dev/null ; then
                        echo "$x_prefix $x_suffix $y_suffix" >> output.log
                    fi  
                    y_matched=1
                    continue
                fi  
            fi  
        fi  
    done    

    if [ $y_matched -ne 1 ]; then
        echo "$x_a NA  NA" >> output.log
    fi  

done

要将xy转换为数组,我确定如果它是单个字符串,你可以找到相同的方法

答案 2 :(得分:0)

fireOnChange()救援!

awk

将生成

awk -v OFS='\t' '{k=$1 FS $2 FS $3}
         NR==FNR {a[k,++c[k]]=$4 OFS $5; next}
                 {if((k,++d[k]) in a) print $0, a[k,d[k]]; 
                  else print $0, "NA", "NA"} '  <(echo "$y") <(echo "$x") | 
column -t