繁体   English   中英

使用Vi / Vim用搜索结果替换每一行中的字符串

[英]Replace string in every line with a search result using Vi/Vim

我有一个显示ls输出的文件

例如

/home/john/A_2014.jpg
/home/john/B_2014.jpg
/home/john/C_2014.jpg
/home/john/D_2014.jpg

现在,我想使用此输出为mysql编写一个插入脚本。 我实现了在每行的开头和结尾处输入必要的代码,因此文件实际上如下所示:

INSERT INTO myimages (name,picture) values ('#name',LOAD_FILE('/home/john/A_2014.jpg'));
INSERT INTO myimages (name,picture) values ('#name',LOAD_FILE('/home/john/B_2014.jpg'));
INSERT INTO myimages (name,picture) values ('#name',LOAD_FILE('/home/john/C_2014.jpg'));
INSERT INTO myimages (name,picture) values ('#name',LOAD_FILE('/home/john/D_2014.jpg'));

有没有一种方法可以将#name替换为_2014.jpg之前的字符串,以便最终输出看起来像

INSERT INTO myimages (name,picture) values ('A',LOAD_FILE('/home/john/A_2014.jpg'));
INSERT INTO myimages (name,picture) values ('B',LOAD_FILE('/home/john/B_2014.jpg'));
INSERT INTO myimages (name,picture) values ('C',LOAD_FILE('/home/john/C_2014.jpg'));
INSERT INTO myimages (name,picture) values ('D',LOAD_FILE('/home/john/D_2014.jpg'));

不幸的是,有很多行可以手动执行此操作。 谢谢你的帮助。

之前

/home/john/A_2014.jpg
/home/john/B_2014.jpg
/home/john/C_2014.jpg
/home/john/D_2014.jpg

命令

:%s@\v.*/([^/]+)_2014.*@...\1...&...@

...A.../home/john/A_2014.jpg...
...B.../home/john/B_2014.jpg...
...C.../home/john/C_2014.jpg...
...D.../home/john/D_2014.jpg...

如你看到的:

  • 使用@作为分隔符
  • 使用\\v使正则表达式非常神奇
  • 使用(...)捕获组,然后将其引用为\\1
  • 使用&引用整个匹配的行

在kev的答案(该答案显示了如何使用向后引用)的基础上,还需要限制要替换“名称”文本的文本。

整个文件的示例(使用:

:%s@\v.*'\zs#name\ze'.*/([^/]+)_2014.*@\1@

\\zs设置比赛的开始位置, \\ze设置结束位置。 这使您可以限制替换的文本。 如kev所述,替换文本中的\\1在搜索模式的(...)组中捕获的文本。 搜索模式本身匹配:

.*    - any text
'     - an opening literal single quote
#name - the literal text, #name
'     - the closing quote
.*    - any text again
/     - the final '/' in the line
(     - start capturing a backreference
[^/]+ - at least one non-slash character (matches A, B, etc.)
)     - end backreference capture
_2014 - matches this text literally
.*    - any other text

替换\\1将整个匹配项替换为捕获的反向引用,但是请记住,我们使用\\zs\\ze将匹配项限制为仅#name字符串。

“宏观+替代”解决方案…

  1. 将光标放在第一行进行编辑,然后将宏记录在寄存器q

     qq 0/_2<CR> yh :s/#name/<Cr>"<CR> q 
  2. 播放您的宏:

     :+,$norm! @q<CR> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM