awkでフィールドを変更すると、文字列全体($ 0)が分割され、OFS(デフォルト<space>
)を使用して再フォーマットされます。フォーマットが維持されるようにこの動作を抑制または変更するにはどうすればよいですか?
たとえば、df -h
フィールド(列)は、1つ以上のタブとスペースで区切られたテーブルを出力します。すべての使用値(フィールド#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
もう1つのトリックは、awkのフィールドセパレータに「シングルスペース」をフィールドセパレータとして使用させることです。これを正規表現などの正規表現として定義し、行の-F'( )'
末尾でカウントダウンされる列の修正を実行します。単一のスペースで区切られているので、最後から2番目の列を「いいね」で簡単にキャッチできます。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が行に正確に1回表示される場合にのみ機能します。
答え3
GNU awkにはSplit()への拡張があります。すべてのフィールドを1つの配列に保存し、すべての実際のフィールド区切り文字(使用されているREと一致)を別の配列に保存します。したがって、色を含めるようにvalue [5]を変更し、ループ内の出力行、インターリーブされたフィールド、および実際の区切り文字を再設定できます。
https://www.gnu.org/software/gawk/manual/gawk.html#String-Functionsそして下にスクロールしてsplit()