有时我需要编写文本,然后将该文本通过管道传输到另一个命令中。我通常的工作流程是这样的:
vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example
rm file.txt
Run Code Online (Sandbox Code Playgroud)
我发现这很麻烦并且正在寻求学习 bash 脚本我想通过编写一个命令来使这个过程变得更加简单,该命令会触发打开一个编辑器,当编辑器关闭时将编辑器的输出通过管道传送到 stdout。然后我就可以将命令作为quickedit | pandoc -o file.pdf.
我不确定这将如何工作。我已经编写了一个函数,通过遵循上面的确切工作流程加上一些附加内容来自动执行此操作。它生成一个随机字符串作为文件名,并在调用函数时将其传递给 vim。当用户通过保存文件退出 vim 时,该函数会将文件打印到控制台,然后删除该文件。
function quickedit {
filename="$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32)"
vim $filename
cat $filename
rm $filename
}
# The problem:
# => Vim: Warning: Output is not to a terminal
Run Code Online (Sandbox Code Playgroud)
我很快遇到的问题是,当我做类似quickedit | commandvim 之类的事情时,它本身无法用作编辑器,因为所有输出都被限制在管道中。
我想知道是否有任何解决方法,以便我可以通过管道传输quickedit函数的输出。次优的选择是启动一个单独的编辑器,比如 sublime text,但我真的想留在终端中。
mur*_*uru 47
vipe 是一个用于编辑管道的程序:
command1 | vipe | command2
Run Code Online (Sandbox Code Playgroud)
您将获得一个具有完整输出的编辑器command1,当您退出时,内容将通过command2管道传递给。
在这种情况下,没有command1. 所以,你可以这样做:
: | vipe | pandoc -o foo.pdf
Run Code Online (Sandbox Code Playgroud)
或者:
vipe <&- | pandoc -o foo.pdf
Run Code Online (Sandbox Code Playgroud)
vipe获取EDITOR和VISUAL变量,因此您可以使用它们来打开 Vim。
如果你还没有安装它,vipe可以在moreutils包中找到它;sudo apt-get install moreutils,或者任何你喜欢的口味。
Wil*_*ard 24
您可以在 Vim 中执行此操作:
:w !pandoc -o file.pdf
Run Code Online (Sandbox Code Playgroud)
或者甚至将缓冲区写入复杂的管道:
:w !grep pattern | somecommand > file.txt
Run Code Online (Sandbox Code Playgroud)
然后你可以不保存就退出 Vim:
:q!
Run Code Online (Sandbox Code Playgroud)
但是,考虑到您的特定用例,将其vi用作命令行编辑器可能有更好的解决方案。假设您使用bash:
set -o vi
Run Code Online (Sandbox Code Playgroud)
这会将您的键绑定设置为vi. 所以,你可以直接使用基本的命令行编辑命令vi键绑定按<Esc>,然后键入vi如命令x,cw等等。(您可以通过按回到插入模式i。)
更好,与这个问题更相关的是,您可以打开 Vim 直接创建命令行内容。 只需键入<Esc>v,您将获得一个空的 Vim 缓冲区。当您保存并退出时,这是您命令行上的命令,它会立即运行。这比直接在命令行上编辑要灵活得多,因为您可以根据需要编写整个迷你脚本。
因此,例如,如果您想编写一些棘手的文本并立即将其通过管道传输到 pandoc,您只需键入:
<Esc>v
Run Code Online (Sandbox Code Playgroud)
然后编辑 Vim 缓冲区,直到你有类似的东西:
cat <<EOF | pandoc -o file.pdf
stuff for pandoc
more stuff for pandoc
EOF
Run Code Online (Sandbox Code Playgroud)
然后保存并退出(使用:x),整个过程将作为 shell 命令运行。
它也将在您的 shell 的命令历史记录中可用。
Joh*_*024 19
尝试:
quickedit() ( trap 'rm ~/temp$$' exit; vim ~/temp$$ >/dev/tty; cat ~/temp$$ )
Run Code Online (Sandbox Code Playgroud)
关键是,要想vim正常使用,vim需要以stdout为终端。我们在这里使用 redirect 来完成>/dev/tty。
为了安全起见,我将临时文件放在用户的主目录中。有关这方面的更多信息,请参阅Greg 的常见问题解答 062。这消除了使用晦涩文件名的需要。
当vim打开时,我输入This function succeeded.并保存文件。屏幕上的结果如下所示:
$ quickedit | grep succeeded
This function succeeded.
Run Code Online (Sandbox Code Playgroud)
即使 的输出quickedit被重定向到管道,vim仍然可以正常工作,因为我们已经给了它直接访问/dev/tty.
正如我在评论中提到的,vim 可以通过管道将文件传递给命令。例如,从 vim 中发出命令:w !pandoc -o file.pdf(注意:w 和 ! 之间的空格是必不可少的)。
确保将vim其设置为您的默认编辑器(例如export EDITOR=vim在您的.bash_profile或 中.bashrc。然后,在任何提示下,您可以键入Ctrl-X后跟Ctrl- E。这将在您配置的编辑器中打开您当前的命令行(例如vim)。进行编辑、保存和退出,并且该命令将被执行,就像您在命令行中键入它一样,包括管道等。