Có thể ống lệnh vim để vim?


18

Tôi muốn chạy shell sau.

wea-this is the end of the second word | vim j
exit 0

Mà tôi đã hy vọng sẽ chuyển các nét chính w(di chuyển về phía trước một từ) sau đó e(cuối từ) rồi a(nối) sau đó -this is the end of the second word(văn bản) vào tài liệu Vim có tên jđã có từ trong đó.

Đã xảy ra lỗi sau khi tôi chạy tập lệnh shell.

/root/bin/tt.sh: line 1: wea-this: command not found
Vim: Warning: Input is not from a terminal

Tôi đang chạy Ubuntu 14.04. Hai loại câu trả lời sẽ được đánh giá cao:

  1. Làm thế nào để sử dụng đường ống để đạt được kết quả mong muốn này.
  2. Một phương pháp khác mà tôi có thể sử dụng "lệnh Vim" (không phải lệnh ed hoặc sed) để chỉnh sửa tài liệu văn bản từ tập lệnh shell.

1
Nhân |vật dẫn đầu ra của lệnh này sang lệnh khác. wea-thiskhông phải là một lệnh. Đường ống không thể được sử dụng để đạt được những gì bạn muốn làm; Nó sẽ khiến stdin của Vim là ứng dụng tay trái, không phải bàn phím. Nếu bạn muốn đưa stdin vào một bộ đệm trong vim, hãy khởi động nó bằng một dấu trừ cho tên tệp : echo Hello, world! | vim -.
dash-tom-bang

Câu trả lời:


15

Để chèn chuỗi "hello"trên dòng đầu tiên của tệp j, bạn có thể nhập vào trình bao của mình lệnh sau:

vim +"1 | put! ='hello'" j

  • :1 di chuyển con trỏ đến dòng đầu tiên của bộ đệm
  • :put! ='hello' dán chuỗi "xin chào" phía trên dòng hiện tại

Để chèn chuỗi "hello"và sau đó lưu và thoát tệp:

vim +"1 | put! ='hello' | x" j

Tương tự như trước đây, chúng ta vừa thêm lệnh Ex :xđể lưu và thoát.

Nói chung, bạn có thể thực thi bất kỳ chuỗi lệnh Ex nào trên một tệp, từ trình bao tương tác hoặc từ tập lệnh bash, như sau:

vim +'Ex command1 | Ex command2 | ...' file

Nếu bạn có nhiều lệnh Ex, bạn có thể viết tất cả chúng trong một tệp chuyên dụng (ví dụ được gọi là myExCommands.vim), một lệnh trên mỗi dòng, sau đó từ shell hoặc tập lệnh bạn có thể lấy nguồn đó (bằng lệnh Ex :sourcehoặc phiên bản ngắn :so) như thế này:

vim +'so myExCommands.vim' file

Biên tập

Tôi thấy bạn đã chỉnh sửa câu hỏi của bạn.
Tôi nghĩ rằng câu trả lời trước vẫn được áp dụng, bởi vì bạn có thể thực thi bất kỳ lệnh bình thường nào từ chế độ Ex bằng các lệnh Ex :normal:execute.

Ví dụ: giả sử bạn muốn:

  • di chuyển con trỏ trên dòng đầu tiên của bộ đệm ( 1G)
  • di chuyển con trỏ của bạn đến ký tự không phải khoảng trắng đầu tiên trên dòng ( _)
  • di chuyển con trỏ của bạn một từ về phía trước ( w)
  • di chuyển con trỏ đến cuối từ mới ( e)
  • đi vào chế độ chèn sau ký tự dưới con trỏ ( a)
  • chèn chuỗi hello
  • lưu và thoát ( :x)

Để thực hiện việc này trên tệp j, nhập từ trình bao:

vim +"execute 'normal! 1G_weahello' | x" j

Để biết thêm thông tin, xem:

:help +cmd
:help :normal
:help :execute

Tôi đã không làm rõ hoàn toàn mục tiêu của mình. Tôi muốn có thể sử dụng các lệnh vims, chẳng hạn như w để di chuyển về phía trước một từ và như vậy. Tôi sẽ chỉnh sửa câu hỏi của tôi để sửa chữa.
Jason Basanese

@JasonBasan Tôi đã chỉnh sửa câu trả lời của mình, thực hiện các lệnh Ex :normal:executelàm những gì bạn muốn?
saginaw

9

Dưới đây là cách bạn có thể sử dụng các lệnh chế độ bình thường, thay vì chỉ các lệnh ex, để chỉnh sửa luồng được trình bày cho Vim từ stdin. Đây không phải là một ví dụ rất hữu ích, nhưng nó minh họa các kỹ thuật liên quan. Nó giả định rằng vỏ của bạn là bash.

echo "The brown fox jumped." | vim -s <(printf 'wcwred\e:wq! foo\n') -

Phần -cuối bảo Vim đọc văn bản (không phải lệnh) từ stdin. Thông báo -scho Vim thực hiện tổ hợp phím từ tệp được chỉ định. Trong trường hợp này, tệp là đầu ra của sự thay thế quá trình bash. Nó <(...)được thay thế bằng tên của một đường ống được đặt tên. Đầu ra của ống là đầu ra của lệnh trong ngoặc đơn. Con wcwred\etrỏ di chuyển con trỏ theo một từ và thay đổi từ tiếp theo thành red. Việc :wq! foo\nlưu kết quả vào tệp foongay cả khi tệp đó đã tồn tại. Kết quả cuối cùng là một tệp có tên foochứa văn bảnThe red fox jumped.

Để biết thêm về một số chủ đề, xem

:help -file
:help -s

Xem thêm Process Substitutionphần của bash(1)trang người đàn ông.


Đã thêm vào ~ / .zshrc : vimx () { vi -s <(echo "$1"':wq') "$2" &> /dev/null; }. Bây giờ tôi có thể vimx 'iThe brow fox jumped.\e' foo; vimx 'wcwred\efjdwiclimbed\e' foo; cat foo. Khéo léo!
Leonard Pauli

4

Tôi đã tìm thấy phương pháp lấy đầu ra của một chương trình được chuyển hướng từ lớp vỏ phụ rất dễ dàng:

vim <( program )

Thí dụ:

 vim <( grep -nH  hello  myFile.cpp )
 vim <( find . -name '*.cpp' -exec grep -nH code_expr {} \+ )

4

Tôi có cùng mong muốn giống như bạn: Tôi muốn viết các lệnh vim bình thường và để chúng chỉnh sửa luồng đường ống. Tôi đã thất vọng bởi sự khó khăn khi sử dụng vim bình thường theo cách này (rất nhiều cờ!), Như được cung cấp bởi các tùy chọn vim mặc định.

Do đó, tôi đã viết một trình bao bọc nhỏ trên vim để làm điều đó: https://github.com/MilesCranmer/vim-stream/ . Nó được gọi là vims.

Trung tâm của trình bao bọc là lệnh sau:

vim - -nes "${vim_cmds[@]}" -c ':q!' | tail -n +2

Sử dụng điều này, với thế hệ lệnh tôi làm, nó hoạt động khá ngắn gọn và vì vim là một trình soạn thảo phương thức, tôi đã tạo vimsmột trình soạn thảo luồng phương thức. Có ba chế độ chính hữu ích cho tâm lý chỉnh sửa đường ống:

[-t|--turn-off-mode] - (Default mode)
                       Every string is a vim command line, e.g., '%g/foo/d' deletes
                       all lines with foo.
[-e|--exe-mode] -      Translated to '%g/$1/exe "norm $2"', see examples below
[-s|--simple-mode] -   Like exe-mode, but runs on 1st line only

Coi đây nè:

$ echo "Hello World" | vims -s "ea Beautiful"
Hello Beautiful World

Vì vậy, eđi đến cuối Hello, sau đó abắt đầu nối thêm.

Một cái gì đó fancier, trong chế độ exe, để nhận xét các dòng có chứa my_bad_varvà xóa dòng trước đó.

cat my_script.cpp | vims -e 'my_bad_var' 'I//\<esc>kdd'

Dịch nghĩa là vims '%g/my_bad_var/exe "norm I//\<esc>kdd"'- Ilệnh bắt đầu chèn vào đầu dòng và //là chuỗi nhận xét. \<esc>kddnhấn phím thoát, di chuyển lên một dòng, sau đó xóa dòng.

Tôi có 11 ví dụ tổng thể về repo, tôi khuyến khích bạn kiểm tra chúng. Một lần nữa, điều này đang chạy trên đỉnh vim, đó chỉ là một cách để làm cho vim giống như sed cho đầu vào luồng (nhưng bảo toàn tất cả các macro vim yêu quý của bạn!)


3

Đây là một câu hỏi khá cũ, nhưng tôi cảm thấy rằng đáng để đóng góp rằng nếu bản phân phối / HĐH đã cho của bạn có quyền truy cập moreutils, thì bạn có thể cài đặt nó và chỉ cần sử dụng vipenhư một bổ sung tiêu chuẩn cho vim:

echo foo | vipe # Now you can edit "foo" to be "bar"!

moreutilscũng rất tiện dụng cho các công cụ khác của nó và tôi rất khuyến khích sử dụng chúng nếu bạn là người dùng dòng lệnh nghiêm túc! :) Hãy xem phần giới thiệu của tác giả (liên kết trước) để biết thêm chi tiết.

moreutilsthường có sẵn cho hầu hết các bản phân phối giống như * nix thông qua trình quản lý gói và qua Homebrew trên Mac . Ví dụ...

# Arch Linux and MSYS2 (more below) as part of the `community` repo
pacman -Sy moreutils


# Mac OS and Homebrew
brew install moreutils

moreutilscũng là một phần của kho lưu trữ gói MSYS2 , vì vậy về mặt kỹ thuật bạn cũng có thể sử dụng nó trên Windows. :)

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.