/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
会询问“给定向后范围,可以交换(y/n)吗?”当发出编辑命令时:/Delete/,/endif/p
。
sed
不会有问题,因为它在开始查找第二个地址之前查找第一个地址(因为它是流编辑器)。
答案2
埃德有一个想法“目前的地址"; 您可以使用.n
(打印当前行及其前面的编号)来查看它。当您打开文件时,它被设置为文件的最后一行。
如果使用正则表达式指定地址,则会获得匹配的当前地址的下一行,环绕在文件末尾,因此打开文件后,搜索从第一行开始。
现在,如果你指定一个地址范围with , ed 首先从当前地址开始/pattern1/,/pattern2/
搜索,然后搜索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
$