Làm thế nào để sao chép bốn ký tự đầu tiên của mỗi dòng vào cuối cùng dòng đó?


10

Đưa ra một loạt các dòng trông tương tự như thế này:

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.

Có cách nào để tôi có thể lấy bốn ký tự đầu tiên (năm) và sao chép chúng vào cuối dòng, để nó trông như thế này:

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
Chắc chắn là có :%g/^\d\{4}\d\@!/s/^\(\d\{4}\).*\zs/ \1/.
Sato Katsura

Câu trả lời:


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

là một cách để làm điều đó

  • \v lựa chọn ma thuật, để tránh phải thoát khỏi nhóm ()
  • ^ bắt đầu của dòng
  • \d{4} khớp chính xác bốn chữ số
  • .* phần còn lại của dòng
  • \1 \2 có mẫu phù hợp trong ()

chỉnh sửa: @Jair Lopez đề cập trong các bình luận, biểu thức thông thường có thể được cải thiện hơn nữa:

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

hoặc tương đương

:% s/\v^(\d{4}).*/\0 \1/ 
  • &\0chứa toàn bộ mẫu phù hợp

Để đọc thêm, vimregexregex FAQ


3
:%s/\v^(\d{4}).*/& \1/sẽ là một lệnh ngắn hơn.
Jair López

10

Và một giải pháp với một vĩ mô:

qqyiwA <Esc>pj0q

Nghĩa là:

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

Sau đó, bạn có thể phát lại macro nhiều lần như bạn có 3@a.

Chỉnh sửa Như @evilsoup đã đề cập đến nó trong các bình luận, một cách hiệu quả hơn để thực thi macro trên tất cả các dòng của bộ đệm là sử dụng:

:%normal @q

Tất nhiên bạn có thể thay thế %bằng một phạm vi mô tả các dòng để sửa đổi.


3
Bạn cũng có thể thực thi nó trên mọi dòng với:%normal @q
evilsoup

@evilsoup: Cảm ơn bạn đã đề cập đến điều đó, tôi sẽ chỉnh sửa câu trả lời.
statox

6

Đây là cách mà tôi sẽ làm:

:%norm y4lA <C-o>p

Giải trình:

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

Nếu bạn có quyền truy cập vào các lệnh UNIX tiêu chuẩn, bạn có thể sử dụng AWK:

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

Không thực sự vi / vim, sau đó, hoặc bốn ký tự đầu tiên.
đường ống

1
Xem xét :help filterlà một tính năng Vim tích hợp và xem xét tính năng đó cho phép Vim phù hợp với mô hình UNIX như thế nào, thực tế tôi sẽ nói nó rất vi / vim.
romainl

1

Tôi nghĩ rằng các cơ chế hiện có để làm điều này là tốt hơn, nhưng cũng có thể làm điều này bằng chế độ khối trực quan .

Sao chép ngày tháng:

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

Kết thúc dòng đầu tiên:

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

Dán:

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

Lưu ý rằng bạn chỉ có thể thực hiện 4lthay vìllll
EvergreenTree

@EvergreenTree - Cập nhật.
Sixty feetersdude

0

Từ một dòng lệnh unix (hoặc cửa sổ nếu bạn đã cài đặt công cụ dòng lệnh unix)

sed -e "s/\(....\)\(.*\)/\1\2 \1" < inputFile > outputFile
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.