簡體   English   中英

覆蓋行的腳本的着色輸出?

[英]Coloring output of a script that overwrites lines?

我正在使用它來為腳本/命令的輸出着色:

commandWithOutput | sed -r 's/(pattern)/'"${COLOR_RED}"'\1'"${COLOR_DEFAULT}"'/g'

(這將在命令的輸出中為所有出現的字符串“pattern”着色。)並且它適用於傳統命令。 但是,如果腳本/命令覆蓋其輸出中的行(這可能與終端/控制台有關而不僅僅是標准輸出?),例如:

Building project X:
CXX Building file XYZ.cpp... [123/1034]

行為不符合預期。 我的 sed 仍然會為輸出着色,但覆蓋不再起作用,即:

Building project X:
CXX Building file ABC.cpp... [1/1034]
CXX Building file DEF.cpp... [2/1034]
CXX Building file GHI.cpp... [3/1034]
CXX Building file JKL.cpp... [4/1034]
CXX Building file MNO.cpp... [5/1034]
// and so on...
CXX Building file XYZ.cpp... [123/1034]

有沒有辦法為覆蓋行的腳本/命令的輸出着色?

我嘗試了幾種不同的想法...... IFS=$'\\r' + OP 的sed命令......嘗試使用中間管道( mkfifo )來處理來自commandWithOutput的輸出......嘗試commandWithOutput緩沖 stdout 的一些嘗試和/或 stdin ......但是(到目前為止)只能得到一個awk解決方案來工作,所以 fwiw ...

注意:我假設 OP 的命令在覆蓋一行時生成一個\\r 如果不是這種情況,OP 可以嘗試將其命令的輸出通過管道傳輸到| od -c | od -c查看“行尾”是什么字符,想法是使用所述字符代替我的\\r引用(如下)。


首先,我們將編寫一個小腳本來生成一些數據,(重新)打印前幾行,然后打印一些“獨立”行:

$ cat overwrite
#!/usr/bin/bash

for (( i=1 ; i<="${1}" ; i++ ))
do
    printf "this is a test ... ${i}\r"
    sleep 1
done

printf "\nanother test output \t and a tab\n"

echo "X."

運行上述生成以下輸出:

$ overwrite 3
this is a test ... 3                      << this line is actually printed 3x times with suffixes of '1', '2' and '3'
another test output      and a tab
X.

在此處輸入圖片說明

通過od運行它會在前 3 行的末尾顯示\\r

$ overwrite 3 | od -c
0000000   t   h   i   s       i   s       a       t   e   s   t       .
0000020   .   .       1  \r   t   h   i   s       i   s       a       t
0000040   e   s   t       .   .   .       2  \r   t   h   i   s       i
0000060   s       a       t   e   s   t       .   .   .       3  \r  \n
0000100   a   n   o   t   h   e   r       t   e   s   t       o   u   t
0000120   p   u   t      \t       a   n   d       a       t   a   b  \n
0000140   X   .  \n
0000143

我們現在將看看一個awk解決方案,用於在我們的overwrite腳本的輸出中重新着色特定模式......

首先,我們將為所需的顏色定義開始和清除/重置變量; 對於這個練習,我將使用“紅色”:

$ myred=$(tput setaf 1)           # set our highlight color to red
$ myreset=$(tput sgr0)            # disable coloring

注意:有幾種方法可以定義這些顏色(以及禁用/重置); 我將把它留給讀者來選擇在他們的環境中最有效的方法。

這是我發現有效的一個awk解決方案:

$ overwrite 3 | awk -v ptn="test" -v cstart="${myred}" -v creset="${myreset}" -v RS="[\n\r]" '{ sub(ptn,cstart ptn creset) ; printf $0 RT }'

在哪里:

  • -v ptn="test" - 我們想要重新着色字符串test所有實例; 我們將把它作為awk變量ptn
  • -v cstart="${myred}" - 將我們的高亮顏色代碼(紅色)分配給我們的awk變量cstart
  • -v creset="${myreset}" - 將我們的顏色清除/重置代碼分配給awk變量creset
  • -v RS="[\\n\\r]" - 將我們的輸入記錄分隔符重新定義為\\r\\n
  • sub(ptn,cstart ptn creset) - 用<red> + test + <reset>替換所有test實例
  • printf $0 RT - 打印我們的新行; RT允許我們使用用於解析此記錄的相同RS

運行上述生成:

this is a test ... 3                      << this line is actually printed 3x times with suffixes of '1', '2' and '3', and the 'test' string printed in red
another test output      and a tab        << the 'test' string is printed in red
X.

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM