Як скопіювати перші чотири символи кожного рядка до кінця цього ж рядка?


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 має узгоджений малюнок у межах ()

редагувати: @Jair Lopez згадує у коментарях, регулярний вираз можна вдосконалити:

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

або еквівалент

:% s/\v^(\d{4}).*/\0 \1/ 
  • &і \0містить весь узгоджений візерунок

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


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

@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 - оновлено.
шістдесят футів

0

З командного рядка unix (або Windows, якщо встановлені інструменти командного рядка unix)

sed -e "s/\(....\)\(.*\)/\1\2 \1" < inputFile > outputFile
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.