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
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.