Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vim 如何将列上的数据划分为多个列_Vim_Multiple Columns_Vi - Fatal编程技术网

Vim 如何将列上的数据划分为多个列

Vim 如何将列上的数据划分为多个列,vim,multiple-columns,vi,Vim,Multiple Columns,Vi,我有以下数据块作为示例: 0.1 A 0.2 B 0.3 C 0.1 E 0.2 F 0.3 G ... 当出现新行时,我想将它们分成多行 0.1 A E H ... 0.2 B F I ... 0.3 C G J ... 我可以在vim中使用列编辑模式(Ctrl+V)手动将数据粘贴到一个新的列中,以实现简单的情况,但当新行/r段变为数百段时,这是不可能的。 有没有办法让vim在每次看到空行时将以下数据移动到新列 非常感谢。有很多方法可以满足您的需要,但这里有一个方法是我想出的 for

我有以下数据块作为示例:

0.1 A
0.2 B
0.3 C

0.1 E
0.2 F
0.3 G
...
当出现新行时,我想将它们分成多行

0.1 A E H ...

0.2 B F I ...

0.3 C G J ...
我可以在vim中使用列编辑模式(Ctrl+V)手动将数据粘贴到一个新的列中,以实现简单的情况,但当新行
/r
段变为数百段时,这是不可能的。 有没有办法让vim在每次看到空行时将以下数据移动到新列


非常感谢。

有很多方法可以满足您的需要,但这里有一个方法是我想出的

for i in range(1, 3)
    exe '4,$g/\v0\.' . i . '/exe "normal! ^dWd\<Space>4G?0.' . i . '\<CR>A\<Space>\<Esc>p"'
endfor
现在,对于
g
命令后面的命令:

'/exe "normal! ^dWd\<Space>4G?0.' . i . '\<CR>A\<Space>\<Esc>p"'

在vim专家找到一个单行解决方案之前,您可能需要使用以下自定义函数来执行按索引整数的连接:

"range function to join lines ordered by a "X" pattern where X is an integer 
"This function is an attempt to answer SO question #28259859 by F14r3
function! F14r3_28259859() range
  let pmatch = ""
  let acc = ""
  let oline = a:lastline + 1
  for linenum in range(a:firstline, a:lastline)
    let curr_line   = getline(linenum)
    let cmatch = matchlist(curr_line,'\(\d\+\) \(.\+\)')
    if (acc=="")
      let acc = curr_line
      let pmatch = cmatch[1]
    else
      if (pmatch==cmatch[1])
        let acc = acc . " " . cmatch[2]
        if (linenum==a:lastline)
          call setline(oline,acc)
        endif
      else
        call setline(oline,acc)
        let pmatch = cmatch[1]
        let acc=curr_line
        let oline = oline + 1
      endif
    endif
  endfor
  return 0
endfunction
下面是使用它的步骤

0-将函数存储在缓冲区中并将其源代码(:so%

1-从如下输入文件开始:

1 Aaaa
2 Bbbbbbbbbbbbbbbbb
3 Cc
1 Ee  ee
2 F
3 G
'<,'>call F14r3_28259859()
2-运行这个excmd->:sort,您将得到:

1 Aaaa
1 Ee  ee
2 Bbbbbbbbbbbbbbbbb
2 F
3 Cc
3 G
3-以可视方式逐行(V)选择已排序的行并调用(键入)函数(输入F后,通过选项卡要求完成),如下所示:

1 Aaaa
2 Bbbbbbbbbbbbbbbbb
3 Cc
1 Ee  ee
2 F
3 G
'<,'>call F14r3_28259859()
5-如果您对结果满意,请按gv(重新选择)和d删除已排序的行

1 Aaaa Ee  ee
2 Bbbbbbbbbbbbbbbbb F
3 Cc G
6-请注意,此函数包含一个仅用于简单整数的正则表达式;您应该修改它以接受带点的格式“0.1”


希望有帮助。

这里有一个解决方案,它不需要大量的脚本,只使用简单的命令和基于模式的范围。以下内容将对整个文件进行操作,但可用于一系列行

首先,因为看起来每行的开头都有一个很好的索引,所以首先对文件进行排序:

:sort
接下来,检查每个索引行,并将其连接到下一个索引之前的所有行(因为文件现在已排序,所以所有这些行都将在一起,并且在下一个索引之前)。为了使这项工作更容易,只需将“下一个”未使用的索引单独附加到文件末尾的一行上。在这种情况下,0.4。然后运行以下命令:

:for i in range(1,3) | exec 'g#0\.'.i.'#.,/0\.'.(i+1).'/-1j' | endfor
这将依次在匹配“0.1”、“0.2”、“0.3”的行上运行
:g
命令。运行的命令是(例如)
:,/0.2/-1j
,表示“将此行的所有行连接起来,直到下一个匹配“0.2”的行之前”。因此,您的文件现在将如下所示:

0.1 A 0.1 E 0.1 H
0.2 B 0.2 F 0.2 I
0.3 C 0.3 G 0.3 J
0.4
请注意,排序后添加了0.4i,以允许在处理最后一组实际数据行时匹配(I+1)范围

现在很容易去掉额外的索引列:

:%s# 0\.\d\+##g
最后,只需删除排序后添加的额外索引

:%s# 0\.\d\+##g