4

I find myself performing a small shell loop (involving vim) to transform files into the correct line endings for my system. It looks as follows:

for i in *; do vim -c 'set ff=dos' -c 'wq' $i; done

It works. The problem is that the terminal flashes during the loop as vim opens and closes repeatedly. There should be a more elegant way to perform this.


Attempt 1 (-e -s)

I tried -e and -s from :h arguments

for i in *; do vim -e -s -c 'set ff=dos' -c 'wq' $i; done

but it is not doing what I believed it would do. set ff= is an ex command alright, and the command above works if I do not include -s. But if I leave -s out it opens and closes vim just like the original command.


Attempt 2 (:argdo)

I'm afraid of argdo because I never understood how it can perform changes to several buffers without writing them back to disk. And I just run into this exact issue in this attempt. I open all files with vim * and try:

:argdo set ff=unix

But after changing the current file I get:

E37: No write since last change (add ! to override)

I'm probably missing something simple in both attempts. I'm very keen on finding a good solution for attempt 1, since it is easier to automate.

What is the elegant way of performing such a multi-file conversion in vim?

  • If you just want to change the newlines to DOS newlines, maybe Vim is a bit of a clunky tool for it on the command line? – Kusalananda Jun 23 '16 at 12:49
  • @Kusalananda - Whelp, yeah it is kind of brute forcing it. I have a sed script to perform that as well but it does not work properly on AIX. And i cannot be arsed to compile GNU sed on AIX (i already managed to compile vim and it was enough of a pain). – grochmal Jun 24 '16 at 0:44
  • Does the shell program unix2dos work for you? – wbg Jul 3 '16 at 6:20
  • @wbg my biggest problem with dos encoding is on AIX, and AIX misses a lot of programs common to linux distros, unix2dos is one of them. Yes, using AIX (and HP-UX) today is crap, i know, but it isn't me who decides. – grochmal Jul 3 '16 at 12:44
  • I hate when a *nix doesn't have a common tool I rely upon. It might not be hard to compile versus getting vim to compile. – wbg Jul 3 '16 at 17:02
3

You can use the following, it is nearly what you have done (using another example to see difference), you need to add the hidden option:

$ touch a b c
$ cat *
$ vi * +"set hidden" +"argdo r\!ls" +"xall"
$ cat *

a
b
c

a
b
c

a
b
c

set hidden tells vim you can switch buffer without saving them.

If you still want to use your loop, you can do the same:

for i in *; do vim +"r\!ls" +"x" $i; done
  • Do you have something about changing buffers without writing them to disk in your vimrc? When i try to replicate your example only the first file receives the output from ls. Then before vim closes (due to xall) E37: No write since last change (add ! to override) quickly flashes through the screen (terminal scroll locks are a blessing). I'm actually doing vim * +'argdo r!ls' +'xall' because i have not vi alias, but that shall not make a difference. – grochmal Jun 23 '16 at 22:05
  • Yeah you are right, I have set hidden, let me add that. – nobe4 Jun 23 '16 at 22:11
1

I already accepted an answer but I found a simpler way to perform this. Given a couple of files:

$ echo yay > a
$ echo yay > b
$ echo yay > c
$ file *
a: ASCII text
b: ASCII text
c: ASCII text

I can use the several :argdo commands separated by |, this way I do not need to rely on :set hidden:

$ vim -u NONE -c 'argdo set ff=dos | w' -c 'q' *
$ file *
a: ASCII text, with CRLF line terminators
b: ASCII text, with CRLF line terminators
c: ASCII text, with CRLF line terminators

It works similar to :set hidden + :xall in terms of how the command appears on the screen but it writes the files one by one.

  • Nice, you should accept your answer instead of mine :) – nobe4 Jun 28 '16 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.