
当更改 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()