Vim: dán từng dòng


8

Giả sử tôi có một tệp chứa:

xxx
yyy
zzz

và một tập tin khác:

kkk
qqq
ppp

Tôi muốn có được:

xxxkkk
yyyqqq
zzzppp

Có thể trong Vim với một số lệnh? (Tôi đã thử sử dụng VISUAL BLOCK nhưng không thành công).

Trong trường hợp cụ thể của tôi, tôi có hai tệp lớn có nhiều dòng để dán nên câu trả lời cũng có thể là một số lệnh shell nhưng tôi muốn biết liệu có cách nào để thực hiện ngay cả trong cùng một tệp không.

Câu trả lời:


12

Từ dòng lệnh, bạn có thể thử

paste -d '\0' file1 file2 > file3

Điều đó làm chính xác những gì bạn muốn.

Chế độ Visual Block trong vimcũng hoàn toàn phù hợp cho nhiệm vụ này. Bạn có chắc là bạn đã làm đúng? Bạn nên

  • Chuyển đến chế độ khối trực quan
  • Chọn văn bản và nhấn yđể kéo dài
  • Chuyển đến tệp khác, ở góc trên bên trái của dữ liệu được dán (cuối cùng x) và nhấn p.

Tôi đã dán trong Visual Block ... đó chính xác là những gì tôi muốn làm. Cảm ơn bạn.
Fabio F.

1
Ít nhất là với GNU Coreutils, paste -d '' ...cũng hoạt động. Thật thú vị, các trang thông tin và trang thông tin coreutils dường như không ghi lại '\ 0', mặc dù nó được chỉ định trong Thông số Unix duy nhất.
derobert

5

Bạn có thể làm trực tiếp khi chỉnh sửa file1. Gõ :để chuyển sang command modetrong vim. Sau đó gõ:

%!paste -d '' - file2

3

Đây là một cách để làm điều đó trong cùng một tệp chỉ bằng Vim.

Nó liên quan đến một số ánh xạ khóa. Tôi đã nghĩ ra điều này một lần khi tôi muốn sắp xếp một vài danh sách thành các cấu trúc giống như bảng trong văn bản đơn giản.

Điều này phụ thuộc vào phím } (dấu ngoặc nhọn bên phải) để bỏ qua các ranh giới đoạn. (Các dấu ngoặc nhọn được nhân đôi, btw: { bỏ qua phần trên cùng của tệp và } về cuối.)

Vì vậy, giả sử bạn có một tệp dữ liệu như thế này (điều này giả sử rằng dòng # được bật với : set nu ):

+---------------  
| 1 xxx    (cursor on line#1)  
| 2 yyy  
| 3 zzz  
| 4   
| 5 kkk  
| 6 qqq  
| 7 ppp  
+---------------  

Điều quan trọng là dòng số 4 là một dòng trống (không có khoảng trắng), tôi sẽ giải thích lý do tại sao ngay lập tức.

Thực hiện lệnh ánh xạ sau
:: map q mw} jdd'wpkJj

Điều này liên kết phím "q" với chương trình 12 ký tự, tôi sẽ chia nhỏ một số chi tiết bên dưới.

Khi bạn nhấn "q", nó sẽ thực thi chương trình đó; lưu ý rằng con trỏ của bạn, bắt đầu trên dòng số 1 bây giờ nằm ​​trên dòng tiếp theo, sẵn sàng nhấn "q" lần nữa. Bạn có thể nhận thấy có một ký tự khoảng trắng giữa "xxx kkk"; nếu bạn không muốn điều đó thì hãy xem "Điều gì về nhân vật không gian thêm?" bên dưới, gần cuối

+---------------
| 1 xxx kkk
| 2 yyy   (cursor on line #2)
| 3 zzz
| 4 
| 5 qqq
| 6 qqq
| ~
+---------------

Đây là một sự cố của ánh xạ:

   :map q mw}jdd'wpkJj
   ^

Dấu hai chấm đưa bạn vào chế độ lệnh để chúng tôi có thể đưa ra lệnh "bản đồ".

   :map q mw}jdd'wpkJj
    ^^^^^

ánh xạ q liên kết q với chuỗi ký tự sau. Lưu ý rằng "q" chỉ là phím "ánh xạ tới" thông thường của tôi; bạn có thể sử dụng các phím khác. Theo mặc định chữ thường q được ánh xạ để bắt đầu ghi macro; vì tôi hiếm khi (không bao giờ?) sử dụng mà tôi thấy "q" hữu ích hơn cho các macro tiện ích một lần. Bạn cũng có thể sử dụng chữ hoa Q (ví dụ: bản đồ Q) hoặc khóa fnct, v.v.

Bây giờ bất cứ khi nào bạn nhấn "q" (trong chế độ điều hướng), vim sẽ thực hiện chuỗi thao tác bàn phím này:

   mw}jdd'wpkJj

Tất nhiên trông giống như vô nghĩa, vì vậy tôi sẽ chia nhỏ từng hành động (với ^^ bên dưới) để dễ theo dõi những gì đang xảy ra.

mw}jdd'wpkJj
^^

Các mw đánh dấu một vị trí được đặt tên, tên ở đây là 'w'. Tôi sử dụng 'w' theo mặc định (tôi nghĩ đó là vị trí 'w'orking của tôi. Bất kỳ vị trí được đặt tên nào, từ az sẽ hoạt động, miễn là bạn nhất quán.
' W 'sẽ xuất hiện lại sau một chút khi chúng tôi muốn trả con trỏ về dòng này.

mw}jdd'wpkJj
  ^

Ở đây chúng ta có kiểu xoăn phải } sẽ đưa con trỏ xuống ranh giới đoạn tiếp theo; nói cách khác, điều này di chuyển con trỏ đến dòng trống tiếp theo, đó là dòng số 4 trong ví dụ của chúng tôi. (Đây là lý do tại sao dòng số 4 phải là một dòng trống; không có khoảng trắng, nếu không } sẽ không coi đó là một ranh giới.)

mw}jdd'wpkJj
   ^

Các j đi xuống một dòng; đây là điều hướng vi "hjkl" trường học cũ. Bạn có thể cũng có thể sử dụng một mũi tên xuống ở đây, tôi thấy "j" dễ đọc hơn và dễ sử dụng hơn (vì các phím mũi tên không phải luôn ở cùng một vị trí giữa các nhãn hiệu bàn phím máy tính xách tay và máy tính để bàn, nhưng "hjkl "Được đảm bảo luôn ở phía bên phải của bất kỳ hàng chủ nào của bàn phím QWERTY (giúp tốc độ gõ của tôi)).
Dù sao, tại thời điểm này, con trỏ nằm trên dòng # 5.

+---------------  
| 1 xxx
| 2 yyy  
| 3 zzz  
| 4   
| 5 kkk   (cursor on line#5)
| 6 qqq  
| 7 ppp  
+---------------  

mw}jdd'wpkJj
    ^^

Các dd là "dòng delete" chỉnh sửa lệnh, vì vậy nó xóa dòng hiện tại, đó là dòng # 5 với "kkk" trên đó. Xóa dòng cũng đặt nó vào bộ đệm dán mặc định, chúng tôi sẽ sử dụng khai thác để đưa "kkk" trở lại nơi chúng tôi muốn nó trên dòng số 1, bên cạnh "xxx".

mw}jdd'wpkJj
      ^^

Chuỗi 'w (một trích dẫn w) đưa con trỏ trở lại dấu trang của chúng tôi cho "w", đặt con trỏ trên dòng # 1.

mw}jdd'wpkJj
        ^

Chữ thường "p" PUTS bộ đệm mặc định hiện tại (với "kkk", như bạn sẽ nhớ lại) sau con trỏ. Vì bộ đệm chứa những gì từng là dòng số 5, nên tệp của chúng tôi trông giống như bây giờ:

+---------------
| 1 xxx
| 2 kkk    (cursor on line#2, after the freshly restored "kkk")
| 3 yyy
| 4 zzz
| 5 
| 6 qqq
| 7 ppp
+---------------

Lưu ý cách "kkk" đã trở thành dòng # 2. (Tôi không thể dễ dàng minh họa nơi con trỏ đến đó ... nó thực sự nên ở đầu dòng # 2).
Chúng tôi đang ở gần nhưng chưa hoàn toàn ...

mw}jdd'wpkJj
         ^^

Chữ thường k nhảy con trỏ lên đến dòng số 1 (điều hướng "hjkl" một lần nữa) và chữ hoa J nối dòng tiếp theo vào dòng hiện tại, làm cho tệp của chúng ta trông như thế này (con trỏ vẫn ở dòng số 1, ở giữa x & & k '):

+---------------
| 1 xxx kkk    (cursor on line #1, between 'xxx' and 'kkk')
| 2 yyy
| 3 zzz
| 4 
| 5 qqq
| 6 ppp
+---------------


mw}jdd'wpkJj
           ^

J cuối cùng là điều hướng "hjkl" một lần nữa, điều này di chuyển con trỏ xuống dòng # 2 rất tiện lợi vì đó là dòng tiếp theo chúng tôi muốn áp dụng q .
Dù sao đi nữa, nó sẽ trông như thế này:

+---------------
| 1 xxx kkk
| 2 yyy       (cursor on #2)
| 3 zzz
| 4 
| 5 qqq
| 6 ppp
+---------------

Nếu bạn nhấn "q" lần nữa và nó sẽ trông như thế này (lưu ý rằng con trỏ nằm trên dòng số 3).

+---------------
| 1 xxx kkk
| 2 yyy qqq
| 3 zzz        (cursor on #3)
| 4 
| 5 ppp
+---------------

Rửa sạch và lặp lại khi cần thiết. Tôi thấy điều này hữu ích cho các danh sách dài hơn vì nó cho phép tôi (khá) xây dựng các cột một cách không đau đớn.

Đây là một ví dụ dài hơn. Thêm một dòng trống ở hàng số 7 sẽ khiến "ggg" xếp chồng lên nhau trong cột tiếp theo. Sau khi xuống "lll", hãy nhảy con trỏ của bạn trở lại dòng # 1 (xoăn trái, {, hoạt động tốt cho điều đó) và tiếp tục với "mmm". Nếu bạn quyết định rằng bạn không thích cách sắp xếp của nó, hãy giữ u (hoàn tác) một chút và điều chỉnh nơi đường "ranh giới" của bạn bắt đầu lại.

Đây là một trong những điều làm việc dễ dàng hơn nhiều so với nỗ lực để giải thích. Trong khi tôi không nghĩ rằng tôi sẽ sử dụng nó để tham gia hàng ngàn hàng, tôi thấy nó tiện dụng cho hàng chục và đôi khi hàng trăm.

+----------:---------------------------
|   before : after
+----------:---------------------------
|  1 aaa   :  1 aaa ggg mmm sss yyy
|  2 bbb   :  2 bbb hhh nnn ttt zzz
|  3 ccc   :  3 ccc iii ooo uuu
|  4 ddd   :  4 ddd jjj ppp vvv
|  5 eee   :  5 eee kkk qqq www
|  6 fff   :  6 fff lll rrr xxx
|  7       :-------------------------
|  8 ggg 
|  9 hhh 
| 10 iii 
| 11 jjj 
| 12 kkk 
| 13 lll 
| 14 mmm 
| 15 nnn 
| 16 ooo 
| 17 ppp 
| 18 qqq 
| 19 rrr 
| 20 sss 
| 21 ttt 
| 22 uuu 
| 23 vvv 
| 24 www 
| 25 xxx 
| 26 yyy 
| 27 zzz
+----------

Những gì về nhân vật không gian thêm?
Một phần trong hành vi của lệnh Tham gia là nó đặt một khoảng trắng giữa các dòng mà nó tham gia.
Nếu bạn không muốn có khoảng trắng giữa "xxx kkk", bạn có thể
thêm lệnh xóa (x) vào chuỗi:

simple join (space char):  :map q mw}jdd'wpkJj
join + x (kills space):    :map q mw}jdd'wpkJxj
join w/comma:              :map q mw}jdd'wpkJR,^[j

"Tham gia + x" sẽ giết khoảng trống bằng cách sử dụng x ngay sau khi chúng ta nối hai dòng lại với nhau. x trong chế độ Điều hướng sẽ xóa bất kỳ ký tự nào mà con trỏ xảy ra, trong trường hợp này là ký tự khoảng trắng vi phạm.

"Tham gia w / dấu phẩy" thay thế dấu cách bằng dấu phẩy. Điều đó hầu như giống nhau nhưng chúng ta sẽ bước qua phần cuối, khác một chút so với ví dụ trước.

:map q mw}jdd'wpkJR,^[j
                  ^

Các R đặt chúng ta vào chế độ Edit (đặc biệt là Thay thế chế độ, mà sẽ ghi đè lên bất kỳ ký tự với những gì chúng ta gõ).

 :map q mw}jdd'wpkJR,^[j
                    ^

Theo nghĩa đen , gõ một dấu phẩy, ghi đè lên không gian vi phạm tại thời điểm đó.

 :map q mw}jdd'wpkJR,^[j
                     ^^

Và sau đó ^ [ báo hiệu một nhân vật Escape, rời khỏi chế độ Chỉnh sửa và đưa chúng ta trở lại chế độ Điều hướng.
Bây giờ chúng tôi đã sẵn sàng cho j cuối cùng để đưa chúng tôi xuống dòng tiếp theo.

Để ánh xạ một ký tự thoát, bạn cần nhấn ^ Q (windows) hoặc ^ V (linux & unix) sau đó nhấn phím Esc (nếu bạn không, ký tự Esc sẽ hủy bỏ lệnh và bên trái bạn tự hỏi tại sao bản đồ có thể phức tạp của bạn định nghĩa vừa tan biến). Đây là trình tự bạn phải nhập để đưa nó vào Vim trên Windows:

:map q mw}jdd'wpkJR,<Ctr-Q><Esc>j

Vì thế. Có lẽ có hàng tá cách để làm điều này Vim.
Khi các dấu phân cách "trường" quan trọng, tôi thường đặt một chuỗi duy nhất đơn giản ở cuối mỗi dòng với tìm kiếm và thay thế toàn cầu, tiếp tục và nối các cột theo cách tôi muốn và sau đó thay thế - tất cả để có dấu phân cách cụ thể mà tôi muốn .

Dù sao, đây chỉ là một ví dụ. Tôi hy vọng bạn thấy nó thú vị.

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.