我有一个示例,如下所示:
输入.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
它不适用于标题行,因为position
和ref
字段之间的空格较少。如果标头是必须的,您可以单独处理:
unexpand -t8 input.txt | awk -F'\t' 'NR == 1 {print $1,$3} $NF ~ /[^ ]/ {print $1, $NF}'