Как скопировать первые четыре символа каждой строки в конец этой же строки?

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/.
Сато Кацура

Ответы:

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

это один из способов сделать это

  • \v магический вариант, чтобы избежать необходимости избегать группировки ()
  • ^ начало строки
  • \d{4} соответствует ровно четырем цифрам
  • .* остаток строки
  • \1 \2 имеет согласованный рисунок в ()

edit: @Jair Lopez упоминает в комментариях, регулярное выражение может быть улучшено:

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

или эквивалент

:% s/\v^(\d{4}).*/\0 \1/ 
  • &и \0содержит весь подобранный образец

Для дальнейшего чтения, vimregex и regex FAQ

Sundeep
источник
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

Конечно, вы можете заменить %его диапазоном, описывающим строки, которые нужно изменить.

statox
источник
3
Вы также можете выполнить его в каждой строке с помощью:%normal @q
evilsoup
@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}'
romainl
источник
Не то чтобы 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
sixtyfootersdude
источник
Обратите внимание, что вы можете просто сделать 4lвместоllll
EvergreenTree
@EvergreenTree - Обновлено.
sixtyfootersdude
0

Из командной строки Unix (или Windows, если у вас установлены инструменты командной строки Unix)

sed -e "s/\(....\)\(.*\)/\1\2 \1" < inputFile > outputFile
Itsme2003
источник