我有一個命令可以創建非常詳細的輸出,大約每秒數百行。但是,該命令用於\r
以類似於進度條的方式覆寫前一行輸出。有時它會向終端寫入換行符,這會「烘焙」當前的輸出行。
當將此輸出重定向到文件時,我得到數百兆的輸出 - 每行都被寫入文件,而不是在發生回車時被「覆蓋」。
我知道這是預期的行為,解決這個問題的一種方法是使程式更智能,並意識到它被重定向到文件而不是列印此交互狀態。但是,我無法修改這個程式。
有什麼方法可以管道/過濾此輸出,以便最終輸出檔案中的內容與在終端上互動式運行它時看到的內容相同?
我試過了:
spammy_cr_command | uniq
……其輸出與沒有相同uniq
並且:
spammy_cr_command | sed '/\r/d'
……這也刪除了包含換行符的「烘焙」行。
答案1
cmd | sed -e 's/.*\r//' > file
這會將每行上回車後的所有文字替換為空,只留下最後回車後的行部分。這不是一定雖然與終端上留下的內容相同,但大多數時候它是一個近似值。
特別是,不處理行比其後繼行長的情況。該程式會給出不正確的結果:
printf 'abcdefg\rxyz\n'
printf '123456789\r\nxyz\n'
因為明顯留下的是
xyzdefg
123456789
xyz
但sed
也會跳過所有未刪除的字元並給出
xyz
xyz
您可以確定您的程式是否有這樣的行為。進度條等將遊標停留在左側邊緣的情況並不罕見,這可能不會給出您想要的結果。
答案2
對於非常原始的 TTY-37 輸出,該命令解決了這個問題,而沒有M. Homer 的答案中提到col
的問題。 sed
(對於不是簡單 TTY-37 輸出且包含終端轉義和控制序列的輸出,該工具col
也不sed
是該工作的工具;但 Stack Exchange 已在那已經快八年了。
%( printf 'abcdefg\rxyz\n' printf '123456789\r\nxyz\n' ) |列b xyz定義 123456789 XYZ %
答案3
可以使用 GNU awk 完成更接近覆蓋行為的操作:
BEGIN {
RS = "[\r\n]" # split records on either CR or LF
a = "" # variable to save the text for overwriting
}
{
a = $0 substr(a, 1 + length) # save current line, add trailing part of saved text
}
RT ~ /\n/ { # LF, time to print and reset
print a;
a = ""
}
使用邁克爾·霍默的例子:
~ awk 'BEGIN { RS="[\r\n]" } {a = $0 substr(a, 1 + length)} RT ~ /\n/ {print a; a=""}' foo
xyzdefg
123456789
xyz
該變數需要 GNU awk ,它包含與該記錄的正規表示式RT
相符的記錄分隔符號文字。RS