views:

770

answers:

5

I'm trying to do the opposite of this question, replacing Unix line endings with Windows line endings, so that I can use SQL Server bcp over samba to import the file. I have sed installed but not dos2unix. I tried reversing the examples but to no avail.

Here's the command I'm using.

sed -e 's/\n/\r\n/g' myfile

I executed this and then ran od -c myfile, expecting to see \r\n where there used to be \n. But there all still \n. (Or at least they appear to be. The output of od overflows my screen buffer, so I don't get to see the beginning of the file).

I haven't been able to figure out what I'm doing wrong. Any suggestions?

A: 

Maybe if you try it this way

cat myfile | sed 's/\n/\r\n/g' > myfile.win

will work, from my understanding your just making the replacements to the console output, you need to redirect output to a file, in this case myfile.win, then you could just rename it to whatever you want. The whole script would be (running inside a directory full of this kind of files):

#!/bin/bash
for file in $(find . -type f -name '*')
do
  cat $file | sed 's/\n/\r\n/g' > $file.new
  mv -f $file.new $file
done
Juparave
-1. doesn't work for me.
Peter
well is platform specific, Jonathan Leffler's answer is better
Juparave
+3  A: 

You don't need the -e option.

$ matches the endline character. This sed command will insert a \r character before the end of line:

sed 's/$/\r/' myfile
mobrule
Thanks for the suggestion, but for some reason this just sticks an r at the end of the file.
John M Gant
According to the info manual to GNU sed: "All the escapes introduced here are GNU extensions, with the exception of `\n'.".
hlovdal
My fault for not specifying the Unix flavor. I'm using AIX. +1 for being the first to point out that I should be searching for $ instead of \n.
John M Gant
+7  A: 
  • What is the problem with getting dos2unix onto the machine?
  • What is the platform you are working with?
  • Do you have GNU sed or regular non-GNU sed?

On Solaris, /usr/bin/sed requires:

sed 's/$/^M/'

where I entered the '^M' by typing controlV controlM. The '$' matches at the end of the line, and replaces the end of line with the control-M. You can script that, too.

Mechanisms expecting sed to expand '\r' or '\\r' to control-M are going to be platform-specific, at best.

Jonathan Leffler
This did the trick. I might be able to get dos2unix on there, but I was hoping to use existing software. I'm on AIX. I assume it's the non-GNU version. Now that you mention it I've used the control-v control-m trick in vi before, should have thought of that. Thanks.
John M Gant
+2  A: 

When faced with this, I use a simple perl one-liner:

perl -pi -e 's/\n/\r\n/' filename

because sed behavior varies, and I know this works.

dlamblin
Yeah, this is the best portable option. The hand-entered ^M and unreliable \r expansions above are showstoppers.
Andy Ross
+1  A: 

Just adding a \r (aka ^M, see Jonathan Leffler's answer) in front of \n is not safe because the file might have mixed mode EOL, so then you risk ending up with some lines becomming \r\r\n. The safe thing to do is first remove all '\r' characters, and then insert (a single) \r before \n.

#!/bin/sh
sed 's/^M//g' ${1+"$@"} | sed 's/$/^M/'

Updated to use ^M.

hlovdal