Search code examples
windowsvimvieolend-of-line

Vim (7.3.3 Windows 64bit): Add ^M to end of line if there is none (ff=unix)


I have some 100,000+ files with partially mangled data, mixed text+binary files (a single file of jpg image data with http headers), where some header fields have dos style ^M^J line termination, and some only unix style ^J. When vim opens a file like this, it treats it as unix format. So all header lines where there is no ^M, one needs to be added. But this has proven to be very tough.

:1,11s/Cache-Control:.*\zs^M\{0,}$/^M/

doesn't work, and i've tried all kinds of variations of that, even using \=printf("%s","^M") as substitution string. But the result is always a new empty line in the file.

The ONLY way i'm able to add a ^M by a command at all is by

:exe "normal A\<c-q>\<c-m>\<Esc>"

Ok so one way would be to first remove any existing ^M, and then add it by previous. But is there a more elegant, one command solution?

(So that there would be no more misunderstandings, here's a short example of such a file:

HTTP/1.1 200 OK
Server: Apache/2.2.3
(more lines...)
Cache-Control: public, max-age=214748
(more lines...)

ÿØÿá Exif  II*            ÿì

)

Edit/solution: regarding 100,000+ files, here's a version (regarding missing ^M only on cache-control lines) that only matches if ^M is missing (as not all files are mangled, this will save large amounts of time together with "update!"):

:1,11s/^Cache-Control:.\{-}\zs\(^M*$\)\(^M\)\@<!/\^M/i


Solution

  • A single command might look like :v/^M/s/$/\^M/. This uses <C-v><C-m>, which is to say... it inserts a literal ^M character that's escaped with a backslash.