6

我有一堆行,我想分成两列,并从每一列中获取数据。数据看起来像这样:

current_well.well_number
current_well.well_name
current_well.well_type_code
well_location.section
well_location.range

本质上,我想做的是根据期间拆分行,将数据转换为两列,然后获取每列的数据。我知道这可以在 Excel 中完成,但我对解决这个问题的 VI 解决方案非常感兴趣。我知道

%s/\./

将用空格格式化字符串。但是一旦我的数据看起来像:

current_well    well_number
current_well    well_name
current_well    well_type_code
well_location   section
well_location   range

如何获取每列的所有值,以便将其粘贴到另一个应用程序中?

4

12 回答 12

13

linux column 命令非常适合创建列

:%!column -s . -t

然后使用块复制。

于 2013-06-10T18:06:31.063 回答
7

一种选择是使用此对齐插件来排列句点,以便您可以更轻松地在可视块模式下选择一列。例如,如果你这样做:

:%Align \.

你最终会得到:

current_well  . well_number
current_well  . well_name
current_well  . well_type_code
well_location . section
well_location . range

如果您不想使用插件,请尝试用空格填充列。例如对于您的文字:

:%s/\v(.*)\.(.*)/\=printf("%-16s %s", submatch(1), submatch(2))/

这会给你留下:

current_well     well_number
current_well     well_name
current_well     well_type_code
well_location    section
well_location    range

然后,您可以Ctrl-V选择要复制的一列文本。只要确保您选择的列宽比您的最宽值宽。

于 2009-04-24T21:01:35.990 回答
4

我已经多次遇到这个问题。将点更改为制表符会使它们排列得很好,但不是真的。的确,所有列都将从一个制表位开始,但不能保证它们会在同一个制表位上。例如,如果这是您的原始文本:

lt1tab.value1
gt1tabstop.value2

你也是:

%s/\./\t/g

并假设一个制表位是 8 个空格,你会得到:

lt1tab  value1
gt1tabstop    value2

您可能想要做的是删除除最后一列(或您想要的任何一列)之外的所有内容。例如:

%s/^.*\.//

会给你留下:

value1
value2

您可以轻松复制和粘贴。


如果你不必使用 Vim,你可以使用 unixcut来做你想做的事:

cut -f2 -d. input_file > output_file
于 2009-04-24T20:48:27.910 回答
2

我一直这样做,只需用大量空间填充:

%s/./                     /

然后<c-v>在空白处进入块模式,绘制我想要的列位置,<将文本向右移动到我的列,然后按住.。需要几秒钟。

如果您知道要排列的特定列位置,则可以使用另一种方法:转到第一行并开始记录 ( qq),找到您的分隔符 ( f.),插入一堆空格 ( 20i <esc>),将空格删除回特定列 ( d15|),然后向下移动一行 ( j)。然后,您只需按住 shift 并滚动手指@Q多次(或使用 count 10@q),直到所有列都排好。:)

于 2010-12-12T00:15:33.623 回答
1

显然,上述带有块选择和/或 Excel 的方法更容易。但我是一个受虐狂,我决定假设您无权访问其中任何一个,并尝试仅使用 vi 命令来完成。这是我想到的可怕的事情:

我的基本计划是将连接列列表变成两个列表,一个接一个。这基本上包括将每一行分成两行,然后将每隔一行复制到文件末尾。

所以,首先我们必须用这个命令把每一行分成两行:

:%s/\./^M/

接下来,在文件底部摆动并创建一个空行,然后返回第一行。这将有助于以后的可读性。

Go[Esc]
:1

现在,您需要将以下序列映射到您喜欢的键:

:map [Key] mkjddGp'kj

(对于记录,这会标记当前行,删除它下面的行,将该行粘贴到文件底部,返回到您开始的行,然后移动到下一行。)

最后,为列表中的每一行按一次映射键。因此,对于示例列表,您需要按 5 次。确保从列表的第一行开始!!

最后你将拥有以下内容:

current_well
current_well
current_well
well_location
well_location

well_number
well_name
well_type_code
section
range

您现在可以轻松地将每个列表复制到需要放置它们的任何位置。

于 2009-04-24T21:01:05.443 回答
0

一种可能的解决方案:

  1. w(或 W for WORDS)跳转到下一个单词,
  2. CTRL- R CTRL-W获取光标下的单词并将其粘贴到命令行

现在您必须将这些命令链接在一个循环中,然后以您自己的方式输出它们。

于 2009-04-24T20:01:27.600 回答
0

为什么不阻止视觉模式?Cv,选择您想要的,然后将其粘贴到其他应用程序中。对于那种粘贴,你可能应该设置

:set guioptions+=a

也是。

嗯,现在我重新阅读了你的问题。您是在问如何将数据分成列,或者如何将其粘贴到其他应用程序中?


我想我现在明白了(第三次阅读)。

照你做的那样做,得到以前点所在的空间。然后再做一次替换,用制表符替换空格,每个制表符是 15 或其他东西。它会很好地排列它们。然后您可以选择并将它们复制到任何地方。

例如,您也可以匹配正则表达式以选择第二列,但是尽管它像圣诞树一样亮起,但您将无法拉动它。

于 2009-04-24T20:01:34.277 回答
0

Ctrl-VCtrl-G您可以通过键入或Ctrl-QCtrl-G(取决于您是否使用 Windows 插入键映射)然后用鼠标选择来选择 gvim 中的列。

于 2009-04-24T20:05:15.173 回答
0

Ctrl V 选择一列

于 2009-04-24T20:06:13.750 回答
0

我会将点转换为制表符,然后块选择每一列:

:%s/\./ CtrlV-Tab /g

CtrlV然后阻止选择列。

或者,由于您有制表符分隔值,它们将直接粘贴到 Excel 中的列中。

于 2009-04-24T20:41:00.313 回答
0

在文件的顶部:

!}awk -F. '{print $1}' >> %

您将被告知文件已更改。选择L(加载)选项。
在原行下面添加一个空行,回到顶部。

for(i=1;i<=NR;i++);print $2 >> %

再次选择L选项

删除原来的行。
您现在有两组中的第一部分和第二部分。

于 2013-02-05T00:32:54.407 回答
0
nnoremap <BS> v"by:%!column -t -s<C-r>b -o'      '<CR>

这是遵循@NES 和@SergioAraujo 想法的一个很好的解决方案。把它放在你的 vimrc 中。

用法。将光标移动到分隔符。然后按退格键。

解释我们使用命名寄存器 b 来保存我们的分隔符。然后将其替换为列 UNIX 实用程序的 --separator 选项的变量。

Backspace 是一个很好的键,因为在普通模式下与 h 相同。但话又说回来,你也可能会不小心撞到它。

于 2019-07-30T21:45:03.823 回答