
/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
$