【发布时间】:2014-03-04 16:09:43
【问题描述】:
假设我有一个 vi 文件如下:
猫文件1
abc 123 pqr
lmn 234 rst
jkl 100 mon
我想获取每行的第二个字段(即,在本例中为 123、234 和 100)并将其附加到同一行的末尾。 我该怎么做?
输出应如下所示:
abc 123 pqr 123
lmn 234 rst 234
jkl 100 mon 100
【问题讨论】:
假设我有一个 vi 文件如下:
猫文件1
abc 123 pqr
lmn 234 rst
jkl 100 mon
我想获取每行的第二个字段(即,在本例中为 123、234 和 100)并将其附加到同一行的末尾。 我该怎么做?
输出应如下所示:
abc 123 pqr 123
lmn 234 rst 234
jkl 100 mon 100
【问题讨论】:
awk:
$ awk '{NF=NF+1; $NF=$2}1' file
abc 123 pqr 123
lmn 234 rst 234
jkl 100 mon 100
它增加一个字段的数量并将最后一个设置为第二个。那么1 是一个真条件,它被评估为默认的 awk 行为:{print $0}。
也可以
awk '{print $0, $2}' file
它打印整行加上第二个字段。
甚至更短,thanks Håkon Hægland!:
awk '{$(NF+1)=$2}1' file
【讨论】:
awk '{NF=NF+1; $NF=$2}1' file > temp_file && mv temp_file file
:%!awk '{ print $0, $2 }' 后跟 enter 键,这将通过该 awk 命令过滤整个缓冲区。
:help filter。
awk 是在这里使用的最佳工具。我提到了cut 和paste,因为有评论询问使用cut。
在 Vi(m) 中有很多方法可以做到这一点。这是我想到的最简单的:
:%norm 0f<space>yaw$p
解释:
:{range}norm command 在{range} 的每一行上执行普通模式command
% 是一个快捷范围,意思是“缓冲区中的所有行”,因此我们将在缓冲区中的每一行上执行以下内容0 将光标放在当前行的第一列(不是绝对必要,但很好的做法)f<space> 将光标跳转到当前行光标后的第一个 <space>
yaw 拉出单词和光标下的<space>
$ 跳到行尾p 粘贴之前提取的文本【讨论】:
2f<pace> 是一种方法,但我不喜欢计算字符和单词,f<space>; 更笨也更容易。
用mark提示,在vi中就可以了
:%s/\( [^ ]*\)\(.*\)/\1\2\1/
另一种方式,使用 sed
sed -r 's/( [^ ]*)(.*)/\1\2\1/' file
【讨论】:
:%s/\( [^ ]*\)\(.*\)/\1\2\1/