如果连续行在不同列上具有相同的值,则合并它们(AWK)

如果连续行在不同列上具有相同的值,则合并它们(AWK)

$1如果连续行的第四个值 ( $4) 相同 ( ),则我需要合并连续行的第一个值 ( ) I-PER

我设法使用 awk 过滤我需要的值:

awk ' ($4 == "I-PER") {printf $1; printf "\n" }

我还发现了如何合并具有重复列值但不连续的行。

示例(输入):

Comandante  comandante  NP00000 I-PER
de  de  SPS00   I-PER
la  el  DA0FS0  I-PER
Guardia guardia NP00000 I-PER
Civil   civil   NP00000 I-PER
Pamplona    pamplona    NP00000 I-LOC
Poblador    poblador    NP00000 I-PER

示例(输出):

Comandante de la Guardia Civil
Poblador

答案1

如果任何行的条件不满足,则awk避免打印重复的行的另一种解决方案:\n

awk '($4=="I-PER"){ printf SEP$1; SEP=" "; C=1; next } 
      C==1{ SEP=""; print ""; C=0} END{print ""}' infile

示例输入:

Comandante  comandante  NP00000 I-PER
de  de  SPS00   I-PER
la  el  DA0FS0  I-PER
Guardia guardia NP00000 I-PER
Civil   civil   NP00000 I-PER
no I-PER in fourth column
anotherline no I-PER in fourth column
Pamplona    pamplona    NP00000 I-LOC
Poblador    poblador    NP00000 I-PER

输出为:

Comandante de la Guardia Civil
Poblador

答案2

一个快速但有点肮脏的解决方案,使用三元运算符(condition?true:false),它会执行您提供的测试并打印$1后跟空格或换行符:

awk '{printf $4=="I-PER"?$1" ":"\n"}'

输出:

$ <test awk '{printf $4=="I-PER"?$1" ":"\n"}'
Comandante de la Guardia Civil 
Poblador

这是一个使用数组的相当糟糕的替代方法 —— 至少它不会像上面对于多个连续的非行那样产生空行I-PER

awk '{
  if ($4=="I-PER") {a[i++]=$1}
  else if (length(a)>0) {
    for (i in a) {printf a[i]" ";delete a[i]}
    print ""
    }
  }
 END {
  if (length(a)>0) {
    for (i in a) printf a[i]" ";print ""}
  }'

输出:

$ <test awk '{if($4=="I-PER"){a[i++]=$1}else if(length(a)>0){for(i in a){printf a[i]" ";delete a[i]};print ""}}END{if(length(a)>0){for(i in a)printf a[i]" ";print ""}}'
Comandante de la Guardia Civil 
Poblador

相关内容