awk:替换字段时保留输出格式

awk:替换字段时保留输出格式

当更改 awk 中的字段时,整个字符串 ($0) 将被分割并使用 OFS 重新格式化(默认<space>)。如何抑制或更改该行为,从而保留格式?

例如,df -h输出一张表,其中字段(列)由一个或多个制表符和空格分隔。我希望所有使用值(字段 #5)>= 80% 以粗体红色打印并保留表的结构:

df -h | awk '{ if($5 ~ /^[8-9][0-9]/) $5="\033[1;31m"$5"\033[0m"; print $0 }'

该字符串将被重新格式化,OFS=' '从而破坏输出表的格式。使用-v OFS='\t'

df -h | awk -v OFS='\t' '{ if($5 ~ /^[8-9][0-9]/) $5="\033[1;31m"$5"\033[0m"; print $0 }'

将在只需几个空格即可到达下一列的位置放置制表符。强制使用以下命令重新格式化每一行else {$5=$5}

df -h | awk -v OFS='\t' '{ if($5 ~ /^[8-9][0-9]/) {$5="\033[1;31m"$5"\033[0m"} else {$5=$5}; print $0 }'

如果需要更多制表符和空格才能到达列,仍然会破坏表结构。

答案1

另一个技巧是强制 awk 的字段分隔符使用“单个空格”作为字段分隔符,方法是将其定义为 regex 之类的正则表达式,并对从行尾倒数到 的列-F'( )'执行修改,因为最后两列总是用单个空格分隔,所以很容易通过喜欢抓住倒数第二列。Use%$(NF-1)$(NF-1)

df -h \
| awk -F'( )' '$(NF-1) ~ /^([5-9][0-9]|100)/ { $(NF-1)="\033[1;31m"$(NF-1)"\033[0m" }1'

好吧,你也可以使用grep如下:

df -h |grep -P '([5-9][0-9]|100)%(?=\s+/)|' --color

答案2

当使用 gsub 函数更改 $0 的内容(因此不替换特定字段)时,输出将不会重新格式化:

df -h | awk '$5 ~ /[8-9][0-9]|100/ {gsub($5,"\033[1;31m"$5"\033[0m")}1'

仅当 $5 在给定示例中的行中仅出现一次时才有效。

答案3

GNU awk 有 split() 的扩展:它将所有字段存储在一个数组中,并将所有实际字段分隔符(与所使用的 RE 匹配)存储在另一个数组中。因此,您可以修复 value[5] 以包含着色,然后在循环中重新构造输出行,交错字段和实际分隔符。

https://www.gnu.org/software/gawk/manual/gawk.html#String-Functions并向下滚动到split()

相关内容