如何将每行的前四个字符复制到同一行的末尾?


10

给定一系列类似于以下内容的行:

2001 "Some Kind of Title," Author's Name, Publication Name, 1 Mar.
2002 "Some Kind of Title," Author's Name, Publication Name, 12 Oct.
2003 "Some Kind of Title," Author's Name, Publication Name, 8 Apr.
2004 "Some Kind of Title," Author's Name, Publication Name, 3 Jun.

有没有办法我可以抓住前四个字符(年份),然后将它们复制到行的末尾,使其看起来像这样:

2001 "Some Kind of Title," Author's Name, Publication Name, 1 Mar. 2001
2002 "Some Kind of Title," Author's Name, Publication Name, 12 Oct. 2002
2003 "Some Kind of Title," Author's Name, Publication Name, 8 Apr. 2003
2004 "Some Kind of Title," Author's Name, Publication Name, 3 Jun. 2004

7
当然有::%g/^\d\{4}\d\@!/s/^\(\d\{4}\).*\zs/ \1/
佐藤桂

Answers:


17
:% s/\v^(\d{4})(.*)$/\1\2 \1/ 

是做到这一点的一种方法

  • \v 魔术选项,以避免不得不逃避分组 ()
  • ^ 行首
  • \d{4} 精确匹配四位数
  • .* 其余的
  • \1 \2 内有匹配的模式 ()

编辑:@Jair Lopez在评论中提到,正则表达式可以进一步改进:

:% s/\v^(\d{4}).*/& \1/ 

或同等学历

:% s/\v^(\d{4}).*/\0 \1/ 
  • &\0包含整个匹配的模式

有关更多阅读,请参见vimregexregex常见问题解答


3
:%s/\v^(\d{4}).*/& \1/将是一个较短的命令。
贾尔·洛佩斯

10

以及带有宏的解决方案:

qqyiwA <Esc>pj0q

意思是:

qq   Record the macro in the register q
yiw  Yank the text described by the text object iw (inner word): The date
A <Esc>   Append a white space to the end of the line and go back to insert mode
p    Paste the date
j0   Place your cursor on the first column of the next line (to be able to repeat the macro)
q    Stop recording

然后,您可以根据需要重播宏3@a

编辑正如@evilsoup在评论中提到的那样,在缓冲区的所有行上执行宏的更有效方法是使用:

:%normal @q

您当然可以用描述要修改的行%范围代替。


3
您还可以在以下代码的每一行上执行该代码:%normal @q
evilsoup '16

@evilsoup:感谢您提及,我将编辑答案。
statox

6

这是我要这样做的方式:

:%norm y4lA <C-o>p

说明:

:%norm                     "Apply the following keystrokes to every line:
       y4l                 "Yank 4 letters. You could also do 'yiw'
          A                "Add a space to the end
            <C-o>          "Do a single normal command
                 p         "Paste

4

如果您有权访问标准UNIX命令,则可以使用AWK

:%!awk '{print $0" "$1}'

那么,不是vi / vim还是前四个字符。
烟斗

1
考虑到这:help filter是一个内置的Vim功能,考虑到该功能允许Vim适应UNIX范式的程度,我会说实际上是vi / vim。
romainl

1

我认为执行此操作的现有机制更好,但是也可以使用可视块模式执行此操作

复制日期:

gg          # Go to the top of the file
<ctrl>y     # Enter visual block mode
G           # Go to the bottom of the file
w           # Select the first word
"jy         # Copy in to the j register

填充第一行的结尾:

gg      # Top of file
A       # Append the line
        # Some spaces
<ESC>   # Return to command mode

糊:

gg 
# Move right to the length of the longest line
"jp   # Paste the block

请注意,您可以4l代替llll
EvergreenTree

@EvergreenTree-更新。
60

0

从UNIX命令行(或Windows(如果已安装UNIX命令行工具))

sed -e "s/\(....\)\(.*\)/\1\2 \1" < inputFile > outputFile
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.