2

我有一个 shell 命令,它提供了我想在将其传递到另一个命令之前对其进行编辑的输出。这不是可以轻松编辑的常规输出sed等。我目前的做法是:

command-one > tmp
vim tmp
command-two < tmp
rm tmp

我想避免不必要地创建临时文件,而是执行类似的操作,command-one | vim - | command-two但这不起作用,因为 vim 的实际屏幕输出通过管道传输到命令中,而不是对我可见进行编辑。这适用于git commit在使用结果之前等待写入临时文件的命令。

4

5 回答 5

5

您可以使用以下代码编写脚本:

#!/bin/sh 
: ${EDITOR:=/usr/bin/vi} 
: ${TMPDIR:=/tmp} 

TMPFILE=${TMPDIR}/.edpipe$$ 

trap "trap '' 0 1 2 3 15; rm -f $TMPFILE; exit 0" 0 1 2 3 15 

cat >$TMPFILE 
$EDITOR ${1:+"$@"} $TMPFILE </dev/tty >/dev/tty 
cat $TMPFILE 
exit 0

例如,将脚本另存为 edpipe,然后像这样在管道中调用它

ls | edpipe | wc -l
于 2018-03-14T23:56:06.390 回答
3

如上所述,这很困难,因为正如您所指出的,要适应这样的管道,编辑器需要向用户显示一件事并在标准输出上输出另一件事。

但是,如果管道的其余部分不是太长/太糟糕,那么您可以使用 vim 执行以下操作:

$ vim <(first | part | of | pipeline)

这会向 vim 传递一个参数,该参数是输出这些命令的标准输出的命名管道。有效的结果是您得到一个包含该输出的缓冲区。然后在退出之前编辑它:

:w !rest | of | pipeline

rest | of | pipeline在 shell 中运行并将当前缓冲区提供给它的标准输入。您将在 vim 中看到命令的输出,然后您将能够:q!丢弃修改后的缓冲区并返回到您的 shell。

于 2014-07-18T11:50:37.930 回答
2

有一个名为 vipe ( https://linux.die.net/man/1/vipe ) 的工具正是为此目的而设计的:

command | vipe | another-command
于 2020-08-04T10:59:20.763 回答
1

如果你想使用一些随机编辑器(即 的值$EDITOR),你需要使用一个临时文件。大多数编辑器无法在编辑完成时接受整个文件stdin并将其写入stdout

请参阅mktemp(或tempfile在不太可能的情况下您没有mktemp)以获取创建临时文件的安全方法。

于 2013-09-30T16:32:18.100 回答
0

尝试这个:

tmpfile=$(mktemp); command-one > $tmpfile && vim $tmpfile && command-two < $tmpfile && rm $tmpfile
于 2013-09-30T16:35:27.653 回答