命令输出显示在单行上

CJx*_*JxD 5 bash command overwrite

是否有可能获得命令的输出 - 例如tar- 将每行输出写入一行?

用法示例:

tar -options -f dest source | [insert trickery here]
Run Code Online (Sandbox Code Playgroud)

并且输出将显示正在处理的每个文件而不使屏幕移动:每个输出都会覆盖最后一个.可以吗?


编辑:我们似乎有一个可行的答案,但让我们进一步:如何做同样的,但超过5行?您会看到一个滚动输出,不会影响终端的其余部分.我想我已经得到了答案,但我想看看你们的想法.

Dav*_*ave 6

用回车替换换行符.

 tar -options -f dest source | cut -b1-$(tput cols) | sed -u 'i\\o033[2K' | stdbuf -o0 tr '\n' '\r'; echo
Run Code Online (Sandbox Code Playgroud)

说明:

  • cut -b1-$(tput cols):如果tar的输出比终端宽,则截断tar的输出.根据您希望终端移动的程度,这不是必需的.

  • sed -u 'i\\o033[2K':在每行的开头插入一行空白.在-u对sed的选项将其置于缓冲模式.stdbuf -oL sed 'i\\033[2K'也会同样有效.

  • stdbuf -o0 tr '\n' '\r':用于tr通过回车交换换行符.Stdbuf确保输出无缓冲; 没有\n's,在线路缓冲终端上,我们看不到输出.

  • echo:输出最终换行符,以便终端提示符不会占用最后一行.

对于您的编辑建议的问题:

x=0; 
echo -e '\e[s'; 
tar -options -f dest source | while read line; do
      echo -en "\e[u" 
      if [ $x gt 0 ]; then echo -en "\e["$x"B"; fi;
      echo -en "\e[2K"
      echo -n $line | cut -b1-$(tput cols);
      let "x = ($x+1)%5";
done; echo;
Run Code Online (Sandbox Code Playgroud)

随意将所有这些刷到一条线上.这实际上为原始问题提供了另一种解决方案:

echo -e '\e[s'; tar -options -f dest source | while read line; do echo -en "\e[u\e2K"; echo -n $line | cut -b1-$(tput cols); done; echo
Run Code Online (Sandbox Code Playgroud)

它除了VT100代码之外整齐地依赖于任何东西.

  • 或者使用回车符,导致下一行被覆盖:`tr'\ 012''\ 015'` (2认同)