1

In my script, I print backspace symbols in order to implement some UI in console as it's described here.

It works well, but now I want to save the output to my log file (via redirecting stdout). When I read this file using command-line tools such as tail or less I get the final 'output view' of my script (i.e. the completed progress bar in this case) and this behavior is preferred for me. But if I open the log file with vim it shows all written symbols to the file with just escaping backslashes as ^H.

How can I set my vim to display my log file similarly to less or tail here?


Here's an example.

1) The python script:

import sys
import time

for i in range(10):
    if i: sys.stdout.write(chr(8) * 10)
    sys.stdout.write(str(i) * 10)
    sys.stdout.flush()
    time.sleep(0.5)
sys.stdout.write('\n')
sys.stdout.flush()

2) Running the script: python program.py > out.txt

3) The output of the cat out.txt:

$ cat out.txt 
9999999999

4) Displayed content of my vim out.txt:

0000000000^H^H^H^H^H^H^H^H^H^H1111111111^H^H^H^H^H^H^H^H^H^H2222222222^H^H^H^H^H^H^H^H^H^H3333333333^H^H^H^H^H^H^H^H^H^H4444444444^H^H^H^H^H^H^H^H^H^H5555555555^H^H^H^H^H^H^H^H^H^H6666666666^H^H^H^H^H^H^H^H^H^H7777777777^H^H^H^H^H^H^H^H^H^H8888888888^H^H^H^H^H^H^H^H^H^H9999999999
Filipp Voronov
  • 4,077
  • 5
  • 25
  • 32

3 Answers3

2

You could use the following command to replace the special key ^H (see :help i_BS) with backspaces:

:g/\b/while getline('.') =~ '[^\b]\b' | s/[^\b]\b//g | endwhile

Sample input:

0000000000^H^H^H^H^H^H^H^H^H^H1111111111^H^H^H^H^H^H^H^H^H^H2222222222^H^H^H^H^H^H^H^H^H^H3333333333^H^H^H^H^H^H^H^H^H^H4444444444^H^H^H^H^H^H^H^H^H^H5555555555^H^H^H^H^H^H^H^H^H^H6666666666^H^H^H^H^H^H^H^H^H^H7777777777^H^H^H^H^H^H^H^H^H^H8888888888^H^H^H^H^H^H^H^H^H^H9999999999

Output:

9999999999
builder-7000
  • 7,131
  • 3
  • 19
  • 43
  • Can I set up my vim to do it automatically on a startup? Cuz I don't want to type this replacement each time I open my log file – Filipp Voronov May 22 '18 at 06:59
  • Sure, you could add an auto command to your .vimrc. For example, `autocmd BufEnter filename silent! cmd`. Here `cmd` is the command provided in the answer. `filename` can be a search patter, for example `*.log` will apply the auto command to every `.log` file. – builder-7000 May 22 '18 at 07:09
  • yep, i've set it up. But one more issue: vim treats this substitution as modifying the content and thus even if I opened it only for reading (as logs normally opened to) vim asks me to quit via `:q!`. Is there a solution to the problem that avoids this, i.e. that changed only the _view_ of the content in vim, not the content itself? – Filipp Voronov May 22 '18 at 07:16
  • Then you could use: `autocmd BufEnter filename set readonly | cabbrev q q! | silent! cmd`. – builder-7000 May 22 '18 at 07:24
1

You can filter the backspaces, and see the result in vim:

cat out.txt | col -b | vim -
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • Can I set up my vim to do it automatically on a startup? Or I can't and need to do this piping each time I want to open such a log file? – Filipp Voronov May 22 '18 at 07:01
0

This command:

$ file out.txt

shows:

out.txt: ASCII text, with overstriking

This command:

$ cat -v out.txt

shows (hard-wrapping added for readability):

0000000000^H^H^H^H^H^H^H^H^H^H1111111111^H^H^H^H^H^H^H^H^H^H
2222222222^H^H^H^H^H^H^H^H^H^H3333333333^H^H^H^H^H^H^H^H^H^H
4444444444^H^H^H^H^H^H^H^H^H^H5555555555^H^H^H^H^H^H^H^H^H^H
6666666666^H^H^H^H^H^H^H^H^H^H7777777777^H^H^H^H^H^H^H^H^H^H
8888888888^H^H^H^H^H^H^H^H^H^H9999999999

And this command:

$ xxd out.txt

shows:

00000000: 3030 3030 3030 3030 3030 0808 0808 0808  0000000000......
00000010: 0808 0808 3131 3131 3131 3131 3131 0808  ....1111111111..
00000020: 0808 0808 0808 0808 3232 3232 3232 3232  ........22222222
00000030: 3232 0808 0808 0808 0808 0808 3333 3333  22..........3333
00000040: 3333 3333 3333 0808 0808 0808 0808 0808  333333..........
00000050: 3434 3434 3434 3434 3434 0808 0808 0808  4444444444......
00000060: 0808 0808 3535 3535 3535 3535 3535 0808  ....5555555555..
00000070: 0808 0808 0808 0808 3636 3636 3636 3636  ........66666666
00000080: 3636 0808 0808 0808 0808 0808 3737 3737  66..........7777
00000090: 3737 3737 3737 0808 0808 0808 0808 0808  777777..........
000000a0: 3838 3838 3838 3838 3838 0808 0808 0808  8888888888......
000000b0: 0808 0808 3939 3939 3939 3939 3939 0a    ....9999999999.

So… the backspaces (^H) and the previous strings are all in fact part of the file and Vim, being a plain text editor, shows its actual content.

As expected.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • Of course I know that previous strings are all part of the file (how could vim know about them otherwise?) and thus my question is how to force vim to _apply_ backspaces automatically on opening – Filipp Voronov May 22 '18 at 07:02