我想运行以下shell。

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


我希望先将击键w(向前移动一个单词),然后将e(该单词的末尾)传递给a(附加),然后-this is the end of the second word(文本)到已经包含单词的Vim文档j

运行shell脚本时发生以下错误。

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


我正在运行Ubuntu 14.04。
两种类型的答案将不胜感激:


如何使用管道系统来达到所需的结果。 />我可以使用“ Vim命令”(不是ed或sed命令)从Shell脚本编辑文本文档的另一种方法。


评论

|字符将一个命令的输出传递给另一个命令。 wea-这不是命令。管道也不能用来实现您想要的目的;这会使Vim的stdin成为左手应用程序,而不是键盘。如果要将stdin放入vim的缓冲区中,请以减号开头的文件名开始:echo Hello,world! | vim-。

#1 楼

要将字符串"hello"插入文件j的第一行,可以在shell中键入以下命令:

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



:1将光标移动到缓冲区的第一行

:put! ='hello'将字符串“ hello”粘贴到当前行上方

要插入字符串"hello",然后保存并退出文件:

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

和以前一样,我们刚刚添加了保存并退出的Ex命令:x

更一般而言,您可以执行任何操作来自交互式shell或bash脚本的Ex命令在文件上的顺序,如下所示:

它们都放在一个专用文件(例如vim +'Ex command1 | Ex command2 | ...' file)中,每行一个命令,然后可以从shell或脚本中获取它(使用Ex命令myExCommands.vim或简短版本:source),如下所示:

vim +'so myExCommands.vim' file


编辑

我看到您已经编辑了问题。
我认为前面的答案仍然适用,因为您可以使用Ex命令:so:normal从Ex模式执行任何常规命令。

对于例如,假设您要:


将光标移动到缓冲区的第一行(:execute
将光标移动到该行的第一个非空白字符( 1G
将光标向前移动一个单词(_
将光标移至新单词(w)的末尾
在光标下方的字符(e)之后进入插入模式
插入字符串a

保存并退出(hello

要在文件:x上执行此操作,请从shell中键入:

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


有关更多信息,请参见:

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


评论


我未能完全阐明我的目标。我希望能够使用vims命令,例如w向前移动单词等。我将编辑问题以更正。

–詹森·巴萨尼斯(Jason Basanese)
15年12月29日在18:33

@JasonBasanese我已经编辑了答案,Ex命令:normal和:execute是否可以满足您的要求?

– saginaw
15年12月29日19:00

#2 楼

这是一种可以使用普通模式命令而不是仅ex命令来编辑从stdin提供给Vim的流的方法。这不是一个非常有用的示例,但是它说明了所涉及的技术。

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


最后的-告诉Vim从stdin读取文本(不是命令)。 -s告诉Vim从指定文件执行击键。在这种情况下,该文件是bash进程替换的输出。将<(...)替换为命名管道的名称。管道的输出是括号内命令的输出。 wcwred\e将光标移动一个单词并将下一个单词更改为red。即使该文件已经存在,:wq! foo\n也会将结果保存到文件foo。最终结果是一个名为foo的文件,其中包含文本The red fox jumped.

有关某些主题的更多信息,请参见

:help -file
:help -s


另请参阅Process Substitution bash(1)手册页的第二部分。

评论


添加到我的〜/ .zshrc中:vimx(){vi -s <(echo“ $ 1”':wq')“ $ 2”&> / dev / null; }。现在我可以vimx'i眉毛狐狸跳了。\ e'foo; vimx'wcwred \ efjdwiclimbed \ e'foo;猫富。整齐!

–伦纳德·保利(Leonard Pauli)
18年4月29日在20:02

@LeonardPauli:看起来很有用!错误输出不可用吗?为什么/ dev / null为空?

–MiłoszŁakomy
20 Jan 3 '20在2:37



资源链接:linux.die.net/man/1/bashgnu.org/software/bash/manual/html_node/…en.wikipedia.org/wiki/Process_substitution

–MiłoszŁakomy
20年1月3日,下午2:42

#3 楼

我发现将程序输出从子Shell重定向的方法非常简单:

vim <( program )


示例:

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


#4 楼

我和您有着完全相同的愿望:我想编写普通的vim命令并让它们编辑管道流。我对默认的vim选项提供的以这种方式使用普通vim的困难感到失望(

),因此,我在vim上写了一个小的包装来做到这一点:https ://github.com/MilesCranmer/vim-stream/。称为vims

包装器的核心是以下命令:

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


使用此命令,与我生成的命令一起使用非常简洁,并且因为vim是模式编辑器,所以我将vims设为模式流编辑器。有三种主要模式可用于管道编辑思维:

[-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//exe "norm "', see examples below
[-s|--simple-mode] -   Like exe-mode, but runs on 1st line only


观看此内容:

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


因此,e移至Hello的末尾,然后a开始追加。

在exe模式下,有些东西注释掉包含my_bad_var的行,并删除前一行。
cat my_script.cpp | vims -e 'my_bad_var' 'I//\<esc>kdd'


转换为vims '%g/my_bad_var/exe "norm I//\<esc>kdd"'-I是命令
开始在行的开头插入,//是注释序列。
\<esc>kdd按下

我在仓库中总共有11个示例,建议您检查一下。同样,这是在vim之上运行的,这只是使vim更像sed一样用于流输入的一种方法(但保留了所有您钟爱的vim宏!)

#5 楼

这是一个相当老的问题,但是我认为值得一提的是,如果您给定的发行版/ OS可以访问moreutils,那么您可以安装它并简单地将vipe用作vim的标准添加:

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


moreutils也非常方便使用其他工具,如果您是认真的命令行用户,我强烈建议您使用它们! :)请查看作者的简介(上一个链接)以获取更多详细信息。

moreutils应该通常通过软件包管理器和Mac上的Homebrew提供给大多数* nix发行版。例如...

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


# Mac OS and Homebrew
brew install moreutils


moreutils也是MSYS2软件包存储库的一部分,因此您也可以在Windows上使用它。 :)