This is a hack but if a direct solution can't be found perhaps it will do (I have an idea of how to do it purely with vim but need to try it later).
Try the print command :[range][p]rint [flags] with l as a flag. This will replace tabs with ^I (two characters). Then use sed to replace with actual tabs.
For example, to output an entire file:
vim -e -s -c'%p l|q!' foo.txt | sed 's/^I/\t/g'
(The -s (silent mode) flag keeps the screen from jumping.)
Update: Okay, I'm not seeing any simple way to do this. Almost everything strips the tabs. Best I can come up with is still hacky but at least it's pure vim. It'll only work with *nix systems with the special file /dev/stdout.
You need a custom function. One approach is to put it in a file and source it. Here's the function:
func! DumpToStdout()
redi! > /dev/stdout
for line in getline(1, '$')
echo line
endfor
redi END
endfunc
If I put it in, say, dump.vim then the vim/ex command is
vim -e -S dump.vim -s -c 'call DumpToStdout()' -c 'q!' foo.txt
(Actually, you could probably cram the function contents into the command line and avoid the need for the extra file but...yuck.)
%pthere, so I think it has the shortcoming that tabs won't work as you mentioned... – filbranden Mar 14 '20 at 14:29