当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 18 篇帖子 ]  前往页数 1, 2  下一页
作者 内容
1 楼 
 文章标题 : vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-15 21:27 

注册: 2007-12-05 10:57
帖子: 1003
地址: 金山
系统: ubuntu14.04
送出感谢: 13
接收感谢: 62
比如文件1内容:
1
a1
其他
若干内容
2
a2
其他
若干内容
3
a3
其他
若干内容

比如文件2内容:
1
b1
其他
若干内容
2
b2
其他
若干内容
3
b3
其他
若干内容

如何实现将文件1的a1,a2,a3,......分别用文件2的b1,b2,b3,....替换。


页首
 用户资料  
 
2 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-15 22:01 
头像

注册: 2009-04-11 23:46
帖子: 4130
系统: Arch Linux
送出感谢: 11
接收感谢: 124
录制宏,或者使用脚本语言。


_________________
我的博客 https://blog.lilydjwg.me/
提问的智慧
Arch Linux 中文论坛

我的vimrc: https://git.io/vimrc


页首
 用户资料  
 
3 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-15 23:27 

注册: 2008-05-24 8:30
帖子: 1453
送出感谢: 2
接收感谢: 30
可以使用 paste 命令把这两个文件合并成一个文件,再 sed 或者 vim 的 :s 命令去掉多余的内容。
例如:
代码:
paste 文件1 文件2 | sed '1~4s/\t.*//;2~4s/.*\t//;3~4s/\t.*//;4~4s/\t.*//' > 新文件

这里假定两个文件中都不含制表符。


页首
 用户资料  
 
4 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 15:57 
头像

注册: 2008-12-28 16:01
帖子: 728
送出感谢: 2
接收感谢: 15
用程序来做吧,先用个适合的数据结构把表示一下你的数据,后面就好弄了。


_________________
爱因斯坦会弹钢琴
爱因斯坦会拉小提琴
爱因斯坦会骑自行车


页首
 用户资料  
 
5 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 17:14 

注册: 2007-12-05 10:57
帖子: 1003
地址: 金山
系统: ubuntu14.04
送出感谢: 13
接收感谢: 62
aerofox 写道:
可以使用 paste 命令把这两个文件合并成一个文件,再 sed 或者 vim 的 :s 命令去掉多余的内容。
例如:
代码:
paste 文件1 文件2 | sed '1~4s/\t.*//;2~4s/.*\t//;3~4s/\t.*//;4~4s/\t.*//' > 新文件

这里假定两个文件中都不含制表符。


谢谢,研究了一下这个命令
paste 文件1 文件2 是依次将文件1的每一行后加一制表符然后贴上文件2对应的行上的内容

所以在sed命令中第一行 第三行 第四行 执行s /\t.*// 删除制表符后的内容,第二行执行s/.*\t//删除字表符前的内容,
得到的效果就是:
用文件1的第一行做为新文件的第一行,文件2的第二行做为新文件的第二行,文件1的3,4行作为新文件的3,4行。

最巧妙的应该是1~4,2~4,3~4,4~4,这一组东东的使用。
它们功能照得到效果来看,应该是:
将全文的所有行以4行为一个循环单位,依次执行它们后面的s操作。

最后
除了 两个文件中都不含制表符 的要求外
还要满足 两个文件中的 “其他若干内容“所占的行数必须是固定且相等的。否者1~N这样的功能就不能应用了。


3楼!看到的话再问问:
如果:两个文件中的 “其他若干内容“所占的行数不是固定,且(行数)也不是对应相等的。
有办法吗?


页首
 用户资料  
 
6 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 17:32 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 274
特征是1,2,3这些数字行后面的一行,要替换?

我担心你只是说了一个特例,而不是规律。


_________________
● 鸣学


页首
 用户资料  
 
7 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 17:54 

注册: 2007-12-05 10:57
帖子: 1003
地址: 金山
系统: ubuntu14.04
送出感谢: 13
接收感谢: 62
eexpress 写道:
特征是1,2,3这些数字行后面的一行,要替换?

我担心你只是说了一个特例,而不是规律。


文件一 1,2,3,........下面的一行 替换为文件二 1 ,2,3,....下面的一行

1,2,3,.....单独占一行 在文件一和文件二中都是唯一的,而且也是依次递增的,即3这一行之后,出现的一个数独占一行的话,一定是4


这也应该算个规律吧。

所谓规律,无非能从局部推出全部


页首
 用户资料  
 
8 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 18:04 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 274
如果是这样的规律。脚本可以搞定。vim难。


_________________
● 鸣学


页首
 用户资料  
 
9 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 19:00 

注册: 2008-05-24 8:30
帖子: 1453
送出感谢: 2
接收感谢: 30
代码:
paste file1 file2 | sed '/^[[:digit:]]\+\t[[:digit:]]\+$/{s/\t.*//;N;s/\n.*\t/\n/}; s/\t.*//'

应该可以了吧?先不解释了,我看楼主应该自己能分析出来。


页首
 用户资料  
 
10 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 19:23 

注册: 2008-05-24 8:30
帖子: 1453
送出感谢: 2
接收感谢: 30
刚才没注意行数不是对应相等,这样的话,上面的命令不行,得用更复杂的脚本编程,python 比较方便。


页首
 用户资料  
 
11 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 22:38 
头像

注册: 2011-06-24 9:14
帖子: 59
送出感谢: 1
接收感谢: 2
能实现,但是最好还是写成函数
代码:
function! s:replaceby(file,repeat,num)
    let b=readfile(a:file)
    for i in range(line('$'))
        if fmod(i,str2nr(a:repeat)) == a:num-1
            let line = b[i]
            " write line to current file
            exe (i+1)."put ='".line."'"
            exe (i+1)."del"
        endif
    endfor
endfunction
command! -nargs=* ReplaceBy call <SID>replaceby(<f-args>)


用法:
如果要用文件b中每4行的第2行...替换文件a中对应行数
在文件a中使用命令
代码:
:ReplaceBy b 4 2


如果不是重复相同行数的话,
则用
代码:
        if getline(i) =~ '^\d\+$'

来判断是否替换。


最后由 rykka 编辑于 2012-03-16 22:51,总共编辑了 1 次

页首
 用户资料  
 
12 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 22:42 

注册: 2007-12-05 10:57
帖子: 1003
地址: 金山
系统: ubuntu14.04
送出感谢: 13
接收感谢: 62
aerofox 写道:
代码:
paste file1 file2 | sed '/^[[:digit:]]\+\t[[:digit:]]\+$/{s/\t.*//;N;s/\n.*\t/\n/}; s/\t.*//'

应该可以了吧?先不解释了,我看楼主应该自己能分析出来。


3楼你好 看到话帮忙看看

这条sed命令似乎可以最后一个分号做分界作这样理解:
分号前的部分做匹配和替换
然后再执行分号后的替换

但我执行
代码:
paste a1 b1 | sed '/^[[:digit:]]\+\t[[:digit:]]\+$/{n;s/.*\t//};s/\t.*//'

发现所有数字行没有被;s/\t.*//'执行到
我的理解是/^[[:digit:]]\+\t[[:digit:]]\+$/匹配到数字行,接着根据前面得到的行做一个操作{n;s/.*\t//}
这个操作分两步 n 移到下行 接着做替换s/.*\t// 由于这两步是当作一个操作所以用了{}
然后;后面是新的操作 s/\t.*// 我的理解是这个操作是对分号前操作的到的全文结果重新行执行s/\t.*//操作,即相当于
代码:
paste a1 b1 | sed '/^[[:digit:]]\+\t[[:digit:]]\+$/{n;s/.*\t//}' | sed 's/\t.*//'


但从执行结果来看这个理解好行不太对.这里能解释下吗
另外N 的解释网上看的不是很明白。


最后由 cao627 编辑于 2012-03-16 23:29,总共编辑了 2 次

页首
 用户资料  
 
13 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 22:50 

注册: 2008-05-24 8:30
帖子: 1453
送出感谢: 2
接收感谢: 30
经过试验,基本上用 vim 做到了,过程比较复杂,看看是否符合楼主的要求:

准备工作,不管用什么工具,从文件2中提取出要送给文件1的那些数据,并在最后加上一行随便什么数据(有一行就行),放到一个新文件中。用 sed 实现这一步的例子为:
代码:
sed -n '/^[[:digit:]]\+$/{n;p};$p' file2 > tmpfile


用 vim 同时打开两个文件1 和 刚才生成的临时文件,在垂直分隔的两个窗口(只vim内部split出来的窗口)中编辑,文件1 位于左侧。
代码:
vim -O file1 tmpfile


然后确保右侧编辑缓冲区中光标位于第一行,在激活左侧 file1 的情况下,执行下面这条 vim 命令
代码:
:g/^\d\+$/+1 normal dd^Wlyyj^WhP

其中 ^W 代表 Ctrl-W,要用 Ctrl-V 加 Ctrl-W 输入。

解释:
代码:
g/^\d\+$/+1
        全局查找只包含数字的行,每次找到后,将其下一行作为当前行,执行后面的命令
normal
        执行后面的 normal 模式操作
dd
        删除当前行
^Wl
        换到右侧窗口
yyj
        拷贝一行,光标下移,为下一次拷贝做准备。如果临时文件最后没有多余的一行,则最后一次j命令会失败。
^WhP
        换到左侧窗口后执行粘贴操作



_________________
评价: 3.7% cao627
 
页首
 用户资料  
 
14 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 23:23 

注册: 2007-12-05 10:57
帖子: 1003
地址: 金山
系统: ubuntu14.04
送出感谢: 13
接收感谢: 62
谢谢,思路看懂了,琢磨一下。


页首
 用户资料  
 
15 楼 
 文章标题 : Re: vim能否实现将一个文件的多处内容替换另一个文件的相应内容?
帖子发表于 : 2012-03-16 23:49 

注册: 2008-05-24 8:30
帖子: 1453
送出感谢: 2
接收感谢: 30
再来一个 sed 的版本,更简洁些:
代码:
sed -f <( sed -n '/^[[:digit:]]\+/{s:.*:/^&$/{n;s/.*/:;N;s/\n//;s:$:/}:;p}' file2 ) file1

思路:
先根据 file2 的内容生成一个 sed 脚本,再用这个脚本来修改 file1。从 file2 生成的 sed 脚本是这个样子:
代码:
/^1$/{n;s/.*/b1/}
/^2$/{n;s/.*/b2/}
/^3$/{n;s/.*/b3/}

如果 b1、b2、b3 等地方会有 &、\L 等对 sed 脚本 s 命令来说有特别含义的内容时,这种做法会出问题。


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 18 篇帖子 ]  前往页数 1, 2  下一页

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:Bing [Bot] 和 0 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译