4
/Delete/,/endif/p
?
invalid address
/Delere/,/endif/p
?
no match

Does it mean it understands latin only?

/Dele/,/endif/p
?
invalid address
/Del/,/endif/p
?
invalid address

No, what am I doing wrong? I'm typing out all letters without any mistakes.

I have macOS.

The following is a sample from the file I'm editing that exhibit the same behaviour when editing it using the above ed command:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Editing mappings
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Remap VIM 0 to first non-blank character
map 0 ^

" Move a line of text using ALT+[jk] or Command+[jk] on mac
nmap <M-j> mz:m+<cr>`z
nmap <M-k> mz:m-2<cr>`z
vmap <M-j> :m'>+<cr>`<my`>mzgv`yo`z
vmap <M-k> :m'<-2<cr>`>my`<mzgv`yo`z

if has("mac") || has("macunix")
  nmap <D-j> <M-j>
  nmap <D-k> <M-k>
  vmap <D-j> <M-j>
  vmap <D-k> <M-k>
endif

" Delete trailing white space on save, useful for some filetypes ;)

if has("autocmd")
    autocmd BufWritePre *.txt,*.js,*.py,*.wiki,*.sh,*.coffee :call CleanExtraSpaces()
endif
Kusalananda
  • 333,661
Adam
  • 211
  • 1
    What are you wanting to achieve here ? What is your input containing, what output do you want to produce ? – steve Jun 02 '18 at 10:18
  • I wanted to delete lines between Delete and endif (including the containing lines). Because It did not work, I was just experimenting with printing them out. – Adam Jun 02 '18 at 10:20

3 Answers3

4

The first endif occurs before the first Delete, so ed gets confused about the range being specified "backwards".

You will want to first find the first occurence of Delete, then apply the command from that line down to the next endif:

1,/Delete/
.,/endif/p

The first command will place the cursor on the first line of the file that contains the word Delete, and the second command will print the lines from that line down to the next line that contains the word endif.


If you were to give the same command in vi, it would complain with "The second address is smaller than the first", and vim would ask "Backwards range given, OK to swap (y/n)?" when giving the editing command :/Delete/,/endif/p.

sed would not have an issue as it looks for the first address before it starts looking for the second address (since it's a stream editor).

Kusalananda
  • 333,661
1

Ed has a notion of "current address"; you can see it with .n (print the current line with its number prepended). When you open a file, it's set to the last line of the file.

If you specify an address using a regular expression, you get the next line downward of the current address that matches, wrapping around at the end of the file, so after opening a file, searches start on the first line.

Now, if you specify an address range with /pattern1/,/pattern2/, ed first searches for pattern1 starting from the current address, then for pattern2 starting from the current address. The current address isn't changed between the two searches.

So, when you search for /Delete/,/endif/, the first address matches line 20; then, we start from the last line again, and endif matches on line 18. Because the value for the first address can't exceed the value of the second one, you get an error.

The solution is to use ; to separate the addresses:

In a semicolon-delimited range, the current address (.) is set to the first address before the second address is calculated.

So you can use this:

/Delete/;/endif/p

and you get lines 20-24:

/Delete/;/endif/p
" Delete trailing white space on save, useful for some filetypes ;)

if has("autocmd")
    autocmd BufWritePre *.txt,*.js,*.py,*.wiki,*.sh,*.coffee :call CleanExtraSpaces()
endif

And to delete them, as alluded to in the comments:

ed infile <<'EOE'
/Delete/-;/endif/d
wq
EOE

This uses the address /Delete/- to also remove the blank line before the Delete line.

0

Need /startrange/,/endrange/d. Example

$ cat inp
foo
Delete
these lines
endif
bar
$ ed inp
33
/Delete/,/endif/d
w
8
q
$ cat inp
foo
bar
$

I'd just use sed :

$ sed -i '/Delete/,/endif/d' inp
$
steve
  • 21,892