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.

Input file:

1 line1\
2 line2\
3 line3\
4 \
5 line4\
6 \
7 \
8 line5\

Desired output:

1 line1
2 line2
3 line3
4
5 line4
6
7 line5

Is it possible with POSIX ed?

Removing the trailing backslashes is easy, but how can I also handle consecutive blackslashes as expected output?

share|improve this question
1  
The FAQ says "You should only ask practical, answerable questions based on actual problems that you face." Using ed for this instead of sed | cat -s doesn't seem practical or a problem that anyone would actually face, so I think this question should be closed. –  Kyle Jones Dec 9 '12 at 21:25
    
I am asking ed, not your sed wise , cat squeeze I know very early. I wrote Assembly LDA load accumlator in 1979. It is I want ed for the whole file read. If you are not there, well. –  user28512 Dec 10 '12 at 17:07

2 Answers 2

up vote 2 down vote accepted

Do not know how to do this in one go. But if the contents is well known one could add a unique string to double lines.

# Add XX to lines that should be deleted
g/^$/+1s/^$/XX/
# Delete them
g/XX/d

Not very nice tho.

share|improve this answer
    
Thank you! tested it and it works. Is g/^$/+1s//XX/ the same thing? –  user28512 Dec 10 '12 at 12:47
    
@user28512 Yes, and so is v/./+1s/^$/XX/. Note that all those solutions would fail if the last-line is empty and would only remove two consecutive lines (use v/./+1,/./s/^$/XX/ for more than two). Why would you want to use ed anyway? –  Stéphane Chazelas Dec 10 '12 at 14:36
    
You loveed? The v will kick me to grep's v of it is negate. Per POSIX line has to have a \n, not many people knows. @Stephane Chazelalas please write some on ed for the public. –  user28512 Dec 10 '12 at 16:33

With sed, you could do:

sed 's/\\$//;/./,/^$/!d'

One of the main problems with ed (beside its syntax from another age) is error handling in script.

Basically, you have to think of it as ed returns success if it successfully edited the file. But to be a successful edit, you have to have each commands address to be valid, each command to be successful (for instance, for the s command, that means at least one substitution done).

So, if you want to check that the edit was successful in this case, it can be tricky.

To build up on @Sukminder's solution and attempt to cover the corner cases, one could write:

printf '%s\n' a a . 'g/\\$/s///' ',s/^/a/' 'g/^a$/+1,/./s/^a$//' \
  'v/./d' 'g/^a/s///' '$d' w | ed -s the-file

The g command would fail if the file was empty (because the default address range (1,$) would be invalid, so we need first to add a line at the end of the file (with the a command). ,s/\\$// would fail if there was no line ending in \ so we need to run it only if there are such lines (g/\\$/s///).

Here, instead of inserting a "xx" assuming it's not to be found in the input, we prepend "a" to each line and replace the lines to be removed with an empty line which we remove afterwards.

Hopefully, that ed script will only return a non-zero exit status if it fails to write the file (w command failing). Unfortunately, I've seen ed implementations returning success when failing to write a file when the FS was full.

IMO, ed is best avoided. Nowadays, using perl -pi.back is as portable and more reliable.

share|improve this answer
    
thank you, but I am converting from sed to ed :) –  user28512 Dec 10 '12 at 12:39
    
My great appreciation for your very detail explanations. –  user28512 Dec 11 '12 at 4:29

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.