Làm thế nào để chỉnh sửa nội dung từ đầu vào tiêu chuẩn?


15

Tôi muốn chỉnh sửa nội dung trong vim được tạo động từ dòng lệnh mà chưa có tệp.

Trong ví dụ:

$ echo This is example. | vim /dev/stdin
$ cat /etc/hosts | vim /dev/stdin

nhưng nó không thành công với các lỗi:

Vim: Cảnh báo: Đầu vào không phải từ thiết bị đầu cuối

Vim: Lỗi đọc đầu vào, thoát ...

Có thể đạt được điều đó?


:help stdin... Thật đáng ngạc nhiên khi người ta có thể tìm thấy câu trả lời nhanh bằng cách đặt câu hỏi của họ về tài liệu được xây dựng.
dash-tom-bang

Câu trả lời:


23

Bạn phải sử dụng -thay cho tên tệp trên dòng lệnh:

echo This is example. | vim -

Lệnh trên sẽ mở một bộ đệm không tên chứa đầy văn bản đọc từ đầu vào tiêu chuẩn.


7
Sử dụng một -stdin là khá nhiều tiêu chuẩn cho các công cụ dòng lệnh;
Martin Tournoij

6

Đây chủ yếu chỉ là một ghi chú thú vị về bashreadline, nhưng nếu bạn đặt EDITORbiến môi trường của mình thành vim, nhấn Ctrl+ x+ esẽ mở ra dòng hiện tại vim. Hơn nữa, nếu bạn gõ Meta(Alt/Opt/Esc)+ Ctrl+ e, bash sẽ thực hiện mở rộng tại chỗ trên dòng lệnh hiện tại, nghĩa là:

$ echo $EDITOR # Assuming EDITOR was set

với Meta(Alt/Opt/Esc)+ Ctrl+ esẽ trở thành

$ echo vim # Assuming EDITOR was set

với Ctrl+ x+ esẽ trở thành

1 echo vim # Assuming EDITOR was set
~
~
/tmp/sometmpbufferfile

Lưu ý rằng khi thoát vim, nội dung của bộ đệm vim được thực thi trên dòng lệnh.

Các tính năng này trở nên rất hữu ích đối với tôi khi tôi muốn thực hiện các lệnh nhiều dòng trong bash, chẳng hạn như các vòng lặp hoặc chương trình yêu cầu các câu lệnh ở đây và cung cấp một cách thú vị để lưu một chút lịch sử dòng lệnh để sử dụng sau này.

Vì vậy, để trả lời câu hỏi ban đầu, bạn cũng có thể viết,

$ This is an example

và sau đó nhấn Ctrl+ x+ eđể tải nó lên vim. Ngoài ra bạn có thể có,

 $ $(cat /etc/hosts)

và do Meta(Alt/Opt/Esc)+ Ctrl+ ethen Ctrl+ x+ e, sẽ đặt tất cả các tệp máy chủ trên một dòng và tải nó lên vim(có thể không sử dụng tốt nhất các tính năng này - tuy nhiên, tính hữu ích của các phương thức này có thể được ngoại suy từ một vài ví dụ được thảo luận đây).

Lưu ý rằng tôi giả sử rằng bạn readlineđược đặt thành emacschế độ. Nếu bạn readlineđược đặt thành vimchế độ, bạn có thể dễ dàng khám phá các ràng buộc có liên quan bằng cách sử dụng lệnh:

bind -p

và tìm kiếm edit-and-execute-commandhoặc shell-expand-line, tương ứng được liên kết với các ràng buộc Ctrl+ x+ eMeta(Alt/Opt/Esc)+ Ctrl+ e.


Bạn có thể yêu cầu bash sử dụng các ràng buộc vi thay vì emacs. Sử dụng set -o viđể bật nó lên. Sau đó, bạn chỉ có thể sử dụng vánh xạ trong chế độ bình thường để chỉnh sửa lệnh hiện tại trong trình chỉnh sửa của mình.
Quincy Bowers

1
Để chắc chắn đây là một mẹo hay để chỉnh sửa dòng lệnh bằng vi nhưng có ít nhất hai vấn đề khi sử dụng phương pháp này để đọc văn bản từ stdin: 1. shell-expand-linexóa dòng mới khỏi văn bản mở rộng và 2. edit-and-execute-commandthử thực hiện lệnh được ghi trong bộ đệm , bất cứ điều gì nó được lưu hay không, khi bạn thoát vi.
toro2k

Ái chà, điều này thật tuyệt vời. Tôi học được một điều mới về readline mỗi ngày, có vẻ như ...
tay nắm cửa

2

Trong bash, tôi thấy hữu ích khi sử dụng thay thế quy trình bằng <(command)cú pháp, ví dụ:

vim <(echo This is example.)
vim <(cat /etc/hosts)

Xem thêm:


4
Lưu ý điều này sẽ không hoạt động trong tất cả các vỏ. Tôi nghĩ rằng nó sẽ chỉ làm việc trong bashzsh(và không sh, ksh, dash, fish, csh, tcsh, vv)
Martin Tournoij

@Carpetsmoker Nên hoạt động trong ksh88 trở lên, tôi nghĩ vậy, nhưng đúng vậy, quá trình thay thế không phải là POSIX.
muru

4
Và chú ý đừng lừa mình! Khi bạn khởi động Vim theo cách này, nó sẽ mở một bộ đệm cho một tệp như thế nào /proc/PID/fd/FD. Nếu bạn viết bộ đệm và thoát, Vim không phàn nàn, nhưng tệp bạn đã viết sẽ bị HĐH xóa. Sử dụng -làm tên tệp, bộ đệm đã mở không có tệp nào được liên kết với nó, vì vậy nếu bạn cố thoát mà không có (miễn là bạn không sử dụng lệnh bang hoặc tương tự), Vim sẽ cảnh báo bạn.
toro2k

1
Điều này là tốt bởi vì nó khái quát tốt vimdiff <(echo foo) <(echo bar).
wchargein

@ toro2k Để theo dõi, nó trông giống như sử dụng :next:prevtái đọc dòng và được gì cả. Điều đáng nói là các quy trình không song song với nhau - ví dụ như cat <(sleep 3; echo a) <(echo b)in theo thứ tự - và trong khi catxen kẽ viết và đọc, hãy vimđợi tệp để "đọc xong" trước khi hiển thị tất cả trừ khung bên ngoài.
John P

-1

Nếu việc sử dụng đường ống dẫn đến Vim mới không phải là một yêu cầu, bạn có thể sử dụng khả năng của Vim để kéo đầu ra của lệnh vào bộ đệm hiện tại, cùng với việc có bộ đệm không được hỗ trợ tệp (như với :newhoặc chỉnh sửa tệp không tồn tại)

:read!cat /etc/hosts trong chế độ lệnh sẽ đặt đầu ra vào bộ đệm hiện tại của bạn bên dưới vị trí con trỏ hiện tại.

Ngoài việc phải xóa dòng đầu tiên còn trống khi việc này được thực hiện trên bộ đệm trống, việc này hoạt động tốt và đặc biệt thuận tiện nếu Vim đang chạy.


1
Làm thế nào để trả lời câu hỏi này?
muru

Nó nhận đầu ra của lệnh và đặt nó vào vim.
ewatt
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.