Wie kopiere ich die ersten vier Zeichen jeder Zeile an das Ende derselben Zeile?

10

Angesichts einer Reihe von Zeilen, die ähnlich aussehen:

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.

Gibt es eine Möglichkeit, diese ersten vier Zeichen (das Jahr) zu erfassen und an das Ende der Zeile zu kopieren, sodass es so aussieht:

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
mischen
quelle
7
Sicher gibt es : :%g/^\d\{4}\d\@!/s/^\(\d\{4}\).*\zs/ \1/.
Sato Katsura

Antworten:

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

ist eine Möglichkeit, es zu tun

  • \v magische Option, um nicht der Gruppierung entkommen zu müssen ()
  • ^ Zeilenanfang
  • \d{4} stimmen genau mit vier Ziffern überein
  • .* Rest der Linie
  • \1 \2 hat das passende Muster in ()

edit: @Jair Lopez erwähnt in Kommentaren, der reguläre Ausdruck kann weiter verbessert werden:

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

oder das Äquivalent

:% s/\v^(\d{4}).*/\0 \1/ 
  • &und \0enthält das gesamte übereinstimmende Muster

Weitere Informationen finden Sie in den häufig gestellten Fragen zu Vimregex und Regex

Sundeep
quelle
3
:%s/\v^(\d{4}).*/& \1/wäre ein kürzerer Befehl.
Jair López
10

Und eine Lösung mit einem Makro:

qqyiwA <Esc>pj0q

Was bedeutet:

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

Sie können das Makro dann so oft wiedergeben, wie Sie möchten 3@a.

Bearbeiten Wie @evilsoup in den Kommentaren erwähnt hat, können Sie das Makro effektiver in allen Zeilen des Puffers ausführen:

:%normal @q

Sie können natürlich %durch einen Bereich ersetzen , der die zu ändernden Linien beschreibt.

statox
quelle
3
Sie können es auch in jeder Zeile mit:%normal @q
evilsoup
@evilsoup: Danke, dass du das erwähnt hast, ich werde die Antwort bearbeiten.
Statox
6

So würde ich es machen:

:%norm y4lA <C-o>p

Erläuterung:

:%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
quelle
4

Wenn Sie Zugriff auf Standard-UNIX-Befehle haben, können Sie Folgendes verwenden AWK:

:%!awk '{print $0" "$1}'
romainl
quelle
Also nicht wirklich vi / vim oder die ersten vier Zeichen.
Pipe
1
In Anbetracht dessen, dass :help filteres sich um eine integrierte Vim-Funktion handelt, und wenn man bedenkt, wie gut diese Funktion es Vim ermöglicht, sich in das UNIX-Paradigma einzufügen, würde ich sagen, dass es tatsächlich sehr vi / vim ist.
Romainl
1

Ich denke, dass die vorhandenen Mechanismen dafür besser sind, aber es ist auch möglich, dies im visuellen Blockmodus zu tun .

Kopieren Sie die Daten:

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

Füllen Sie das Ende der ersten Zeile auf:

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

Einfügen:

gg 
# Move right to the length of the longest line
"jp   # Paste the block
sechzig Fuß
quelle
Beachten Sie, dass Sie nur 4lanstelle vonllll
EvergreenTree
@EvergreenTree - Aktualisiert.
Sixtyfootersdude
0

Über eine Unix-Befehlszeile (oder Windows, wenn Sie Unix-Befehlszeilentools installiert haben)

sed -e "s/\(....\)\(.*\)/\1\2 \1" < inputFile > outputFile
Itsme2003
quelle