Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I was working on the conversion of Unix newline to Windows newline. I tried to unix2dos but it gave me some binary error, so I looked it up and stumbled upon this regex

sed 's/$'"/`echo \\\r`/" input.txt > output.txt

This regex is working but I have got no clue, how is it working? Obviously I am trying to interpret it through this form

sed 's/a/b/'

Here

a refers $'" which I don't understand.
and b refers echo \\\r which means '\r'

Also I don't understand why/how combination of single and double quote is being used? Can anyone explain this regular expression to me?

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

There is no $'"

's/$'"/`echo \\\r`/" == "s/\$/`echo \\\r`/"

But the regex author just liked to escape $ via single quote.

You can combine such escaping in any way you like.

So your regex it just appends \r to the end of the line.

update. Initially it wasn't clear from question that it uses `echo \\\r` instead of just echo \\\r. There is no need to use echo here. You can just do it directly in sed:

sed 's/$/\r/'
share|improve this answer
    
Ok, Can't I use '\r' directly instead of using it with echo. –  Dude Nov 15 '13 at 19:39
    
@JoeDimaggio You can use it directly. Initially ` symbol was hidden in your question. I updated my answer. –  rush Nov 15 '13 at 19:44
    
Wow from that regex to this regex! :D. One more question though, It seems like the line-break in windows in \r\nEOL. But I feel like this regex will give /n\rEOL. so what am I missing here? –  Dude Nov 15 '13 at 19:49
    
@JoeDimaggio actually in sed \n is outside working pattern ( except cases when several lines are in the buffer, but even in that case the last \n will be outside the buffer ) and \r will appear just before \n. –  rush Nov 15 '13 at 21:14
add comment

That's some complex quoting. The argument to sed is built up from two parts. First, there's 's/$', a single-quoted string literal, yielding the characters s/$. Then there's a double-quoted string, which contains the command substitution `echo \\\r`. This runs the command echo \r, which depending on the shell either prints \r or a CR character. (The text printed by echo ends in a newline, but the command substitution eats it up.) In order for this command to have the desired effect, you must be on a system where echo \r prints a CR character, which I'll represent here as .

The argument to sed is thus s/$/␍/. This replaces every match of the regular expression $ by the string . The regex $ matches the empty string, but only at the end of a line, so this sed command appends a CR to every line. Since a Unix line ends with LF while a Windows line ends with CR+LF, this transforms Unix line endings into Windows line endings.

GNU sed, but not other versions, understand backslash escapes such as \r. So with GNU sed you can write sed 's/$/\r/'. However, this doesn't work with other sed implementations (BSD, Solaris, …). echo \r isn't very portable either. A portable solution is to use tr, which has backslash escapes as a standard.

sed "$(echo 's/$/@/' | tr '@' '\r')"
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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