Jak skopiować pierwsze cztery znaki każdego wiersza na koniec tego samego wiersza?

10

Biorąc pod uwagę serię linii, które wyglądają podobnie do tego:

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.

Czy istnieje sposób, w jaki mógłbym złapać te cztery pierwsze znaki (rok) i skopiować je na koniec wiersza, aby wyglądało to tak:

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
mieszać
źródło
7
Pewny jest: :%g/^\d\{4}\d\@!/s/^\(\d\{4}\).*\zs/ \1/.
Sato Katsura

Odpowiedzi:

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

jest jednym ze sposobów, aby to zrobić

  • \v magiczna opcja, aby uniknąć konieczności ucieczki przed grupowaniem ()
  • ^ początek linii
  • \d{4} dopasuj dokładnie cztery cyfry
  • .* reszta linii
  • \1 \2 ma pasujący wzór ()

edit: @Jair Lopez wspomina w komentarzach, wyrażenie regularne można ulepszyć:

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

lub odpowiednik

:% s/\v^(\d{4}).*/\0 \1/ 
  • &i \0zawiera cały dopasowany wzór

Do dalszego czytania, vimregex i regex FAQ

Sundeep
źródło
3
:%s/\v^(\d{4}).*/& \1/byłoby krótszym poleceniem.
Jair López
10

I rozwiązanie z makrem:

qqyiwA <Esc>pj0q

Co znaczy:

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

Następnie możesz odtworzyć makro tyle razy, ile masz linii 3@a.

Edytuj Ponieważ @evilsoup wspomniał o tym w komentarzach, bardziej skutecznym sposobem wykonania makra na wszystkich liniach bufora jest użycie:

:%normal @q

Oczywiście można zastąpić %przez zakresu opisujące linie zmodyfikować.

statox
źródło
3
Możesz go również wykonać na każdej linii za pomocą:%normal @q
evilsoup
@evilsoup: Dzięki, że o tym wspomniałem, zredaguję odpowiedź.
statox
6

Oto jak bym to zrobił:

:%norm y4lA <C-o>p

Wyjaśnienie:

:%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
James
źródło
4

Jeśli masz dostęp do standardowych poleceń UNIX, możesz użyć AWK:

:%!awk '{print $0" "$1}'
romainl
źródło
Tak naprawdę nie jest to vi / vim ani pierwsze cztery znaki.
rura
1
Rozważanie :help filterjest wbudowaną funkcją Vima i biorąc pod uwagę, jak dobrze ta funkcja pozwala Vimowi dopasować się do paradygmatu UNIX, powiedziałbym, że w rzeczywistości jest to bardzo vi / vim.
romainl
1

Myślę, że istniejące mechanizmy do tego celu są lepsze, ale można to również zrobić w trybie blokowania wizualnego .

Skopiuj daty:

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

Wpisz koniec pierwszej linii:

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

Pasta:

gg 
# Move right to the length of the longest line
"jp   # Paste the block
sześćdziesiąt stóp
źródło
Pamiętaj, że możesz to zrobić 4lzamiastllll
EvergreenTree
@EvergreenTree - zaktualizowano.
sixtyfootersdude
0

Z wiersza polecenia unix (lub systemu Windows, jeśli masz zainstalowane narzędzia wiersza polecenia unix)

sed -e "s/\(....\)\(.*\)/\1\2 \1" < inputFile > outputFile
Itsme2003
źródło