2

I am currently running Gnu ed version 1.18 in the Debian WSL on Windows. If I edit a file with the following encoding:

ASCII text, with CRLF, LF line terminators

or

ASCII text, with CRLF,

then ed does not properly join lines with the j command. Rather, it deletes the first line meant to be joined.

This problem does not occur if the file is created in ed, but it does affect files that were created in other programs and are then edited in ed. The same problem is found in GNU ed 1.17.

Is this a bug? How would one circumvent this problem?

1
  • 1
    use hexdump, od or hd to view what's really in the file. You won't be able to see the overwritten characters if you just print to the console
    – phuclv
    Commented Jun 25, 2022 at 9:11

1 Answer 1

5

The ed editor will assume that the document is a Unix text file. When presented with a DOS text file (a file with CRLF line-endings) it will treat the carriage-return characters at the end of each line as any other character.

This means that if you have a DOS text file like the following (here viewed using ,l to list the file in an unambiguous way, with the carriage-returns made visible as \r and each end-of-line displayed as $),

line 1\r$
line 2\r$
line 3\r$

... and then use 2,3j to join line three onto the end of line two, you'll get

line 1\r$
line 2\rline3\r$

When ed outputs line 2\rline3\r to the terminal, the cursor is moved back to the start of the line by the literal carriage-return character embedded in the middle of the line, which gives the impression that the text line 2 disappears (it is in fact overwritten by line 3).

The solution is to convert your document to Unix text using a tool such as dos2unix, or, delete all single trailing carriage-returns from within the editor using

,s/^M$//

... where you type ^M using Ctrl+VCtrl+M (this types a literal carriage-return).

In GNU ed release 1.18 and later, you may also choose to start the editor with the --strip-trailing-cr option, which removes any single trailing carriage-return from the end of the lines when you open a file. This is exactly what the s/// command above does.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .