我是VIM的新手,我尝试将文件拆分为多个文件。这是一个测试文件:
Something1;XXXword;blabla(about 500 signs);
Something1;XXXword;(about 500 signs);
Something1;YYYword;(about 500 signs);
Something1;RRRword;(about 500 signs);
XXX可能是2到20个字符的单词。当下面的单词(XXX / YYY / RRR)发生变化之前,#34; Something1"应该是一个剪切,以下行直到XXX更改应该是另一个新文件,依此类推。
应该如此:
File1:
Something1;XXXword;blabla(about 500 signs);Something1;XXXword;(about 500 signs);
File2:
Something1;YYYword;(about 500 signs);
File3:
Something1;RRRword;(about 500 signs)
有没有办法像专业人士那样做?谢谢:))
答案 0 :(得分:6)
我会推荐一种不同的工具,比如Awk。
awk -F';' '{printf "%s", $0 >> $2}' your_file.txt
这会将每一行拆分为由;
分隔的列。每行将附加(>>
)到以第二列$2
命名的文件(例如XXXword)。将新行($0
除外)的整行printf "%s"
附加/打印到新文件中,以便所有内容都是一行。
注意:我使用gawk
作为awk
实施,您可能需要根据awk
实施情况进行调整。
在以下情况下,您有XXX
,YYY
,XXX
:
Something1;XXXword;blabla(about 500 signs);
Something1;YYYword;(about 500 signs);
Something1;XXXword;(about 500 signs);
如果这应该产生3个文件(1 YYY
个文件和2个XXX
个文件),那么我们也可以使用Awk:
awk -F';' 'last != $2 {f[$2]++} {printf "%s", $0 >> $2 f[$2]; last = $2}' your_file.txt
这将生成文件:XXXword1
,XXXword2
和YYYword1
这类似于上面的awk示例,除了我们使用字典/数组来存储第二列从前一行f[$2]++
更改last != $2 {...}
的次数。确保在打印每一行后将last
设置为第二列。将行$0
输出到以$2 f[$2]
命名的文件(相邻变量和字符串将被连接)。
答案 1 :(得分:1)
您必须按照其他任何语言对其进行编程进行编程。我的第一反应就是Perl BTW。
function! s:split(root) abort
" todo: check empty buffers
let lines = getline(1, '$')
let nb_lines = len(lines)
let files = []
let crt = 0
while crt < nb_lines
" I suppose the word is the second field in a .csv file
let word = matchstr(lines[crt], '^[^;]*;\zs[^;]*\ze;')
" This is where the real magic happens, see :h /\@!
let next = match(lines, '^[^;]*;\(\('.word.'\)\@![^;]\)*;', crt)
if next == -1 | let next = nb_lines | endif
let files += [ lines[crt : (next-1)] ]
let crt = next
endwhile
echo files
endfunction
command! -nargs=1 SplitBuffer :call s:split("<args>")
而不是let files += [ something ]
,您需要执行
:let index = 0
...
:for...
...
:call writefile(a:root.index, lines[crt : (next-1)])
:let index += 1
:endfor
编辑:
如果序列XXX
,YYY
,XXX
将导致两个文件而不是3个,则可以使用此(复杂且未经测试的)oneliner完成 - 仍然,更喜欢@Peter Rincker基于awk的解决方案。
:call map(getline(1, '$'), 'writefile(v:val, split(v:val, ";")[1], "a")')