当某些行有空/缺失值时使用 awk 提取数据

当某些行有空/缺失值时使用 awk 提取数据

我有一个示例,如下所示:

输入.txt

   USERS        position   ref   rslt   
    usr1                    X     B   
    usr2          2980            C   
    usr3          3323      P      
    usr4                          A  
    usr5          5251      U      
    usr6          9990            A
    usr7          10345     T     

我需要打印“rslt”列和相应的“USERS”,输出文件应如下所示:

输出.txt

  USERS     rslt   
   usr1       B   
   usr2       C       
   usr4       A
   usr6       A 

我尝试使用awk命令但没有成功。注意,表格的所有黑色位置都填充了空格(每行空格数不同)

答案1

在这种情况下,一种可能的解决方案是在开始部分提供字段的宽度:

awk 'BEGIN {FIELDWIDTHS = "16 11 6 7"} 
    $4 ~/[^ ]/ {print $1 $4}' 

字段宽度可以手动计算,但对于复杂的标题,我喜欢从

 head -1 f | grep -Po '.*? (?=\S|$)' | awk '{print length}'

更新:...或者为了处理标题中的初始和最终空格:

 head -1 f | grep -Po '(^ *|\S).*?( (?=\S)|$)' | awk '{print length}'

答案2

awk命令不是最适合这项工作的工具。使用,它将要提取的字段的字符位置作为参数。因此,在您的示例中指定USERS从字符位置 1 开始,到字符位置 8 结束,并rslt从字符位置 33 开始。

$ cut -c 1-8,33- input.txt
   用户 rslt
    usr1 B
    usr2C
    usr3
    usr4A
    usr5
    usr6A
    usr7

有关如何计算字符位置的信息,请参阅以下内容。

         1 2 3         
123456789012345678901234567890123456789
   用户位置参考 rslt   
    usr1 XB   
    usr2 2980℃   
    usr3 3323 P      
    usr4A  
    usr5 5251 U      
    usr6 9990 A
    usr7 10345 T      

答案3

你可以得到几乎通过使用unexpand实用程序“制表符”输入,然后将awk字段分隔符设置为制表符,并且仅打印最终字段由空格以外的内容组成的行:

unexpand -t8 input.txt | awk -F'\t' '$NF ~ /[^ ]/ {print $1, $NF}'
    usr1   B
    usr2   C
    usr4   A
    usr6   A

它不适用于标题行,因为positionref字段之间的空格较少。如果标头是必须的,您可以单独处理:

unexpand -t8 input.txt | awk -F'\t' 'NR == 1 {print $1,$3} $NF ~ /[^ ]/ {print $1, $NF}'

相关内容