ed неверный адрес macOS

ed неверный адрес macOS
/Delete/,/endif/p
?
invalid address
/Delere/,/endif/p
?
no match

Означает ли это, что он понимает только латынь?

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

Нет, что я делаю не так? Я печатаю все буквы без ошибок.

У меня macOS.

Ниже приведен пример из редактируемого мной файла, который демонстрирует такое же поведение при редактировании с помощью указанной выше edкоманды:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 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

решение1

Первый endifвстречается перед первым Delete, поэтому edвозникает путаница из-за того, что диапазон указан «назад».

Сначала вам нужно будет найти первое вхождение Delete,затемпримените команду с этой строки до следующей endif:

1,/Delete/
.,/endif/p

Первая команда поместит курсор на первую строку файла, содержащую слово Delete, а вторая команда выведет строки от этой строки до следующей строки, содержащей слово endif.


Если бы вы дали ту же команду в vi, он бы выдал сообщение «Второй адрес меньше первого» и vimспросил бы «Указан обратный диапазон, можно ли поменять местами (да/нет)?» при подаче команды редактирования :/Delete/,/endif/p.

sedпроблем не возникнет, поскольку он ищет первый адрес, прежде чем начнет искать второй адрес (так как это потоковый редактор).

решение2

У Эда есть представление о "текущий адрес"; вы можете увидеть это с помощью .n(вывести текущую строку с ее номером, добавленным в начало). Когда вы открываете файл, он устанавливается на последнюю строку файла.

Если указать адрес с помощью регулярного выражения, вы получите следующую строку ниже текущего совпадающего адреса, переходя к концу файла, поэтому после открытия файла поиск начнется с первой строки.

Теперь, если вы укажете адресдиапазонс /pattern1/,/pattern2/, ed сначала ищет, pattern1начиная с текущего адреса, затем — pattern2начиная с текущего адреса.Текущий адрес между двумя поисками не меняется.

Итак, когда вы ищете /Delete/,/endif/, первый адрес соответствует строке 20; затем мы снова начинаем с последней строки и endifнаходим соответствие на строке 18. Поскольку значение для первого адреса не может превышать значение второго, вы получаете ошибку.

Решение состоит в том, чтобы использовать ;для разделения адресов:

В диапазоне, разделенном точкой с запятой, текущий адрес ( .) устанавливается на первый адрес до того, как будет вычислен второй адрес.

Итак, вы можете использовать это:

/Delete/;/endif/p

и вы получаете строки 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

И удалить их, как указано в комментариях:

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

При этом адрес /Delete/-также используется для удаления пустой строки перед Deleteстрокой.

решение3

Нужен /startrange/,/endrange/d. Пример

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

Я бы просто использовал sed:

$ sed -i '/Delete/,/endif/d' inp
$

Связанный контент