在一系列UNIX管道命令中间使用$EDITOR

x759pob2  于 2022-11-04  发布在  Unix
关注(0)|答案(6)|浏览(125)

我有一个shell命令,它提供的输出我想在将它输入到另一个命令之前进行编辑。这不是一个可以用sed之类的命令轻松编辑的常规输出。我目前的方法是:

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

我想避免不必要的临时文件的创建,而代之以像command-one | vim - | command-two这样的命令,但这并不起作用,因为vim的实际屏幕输出被管道传输到命令中,而不是对我来说是可见的,以便编辑。这在像git commit这样的命令中起作用,它在使用结果之前等待临时文件被写入。

ryevplcw

ryevplcw1#

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


# !/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
gudnpqoy

gudnpqoy2#

正如您所指出的,这是很困难的,因为要适应这样的管道,编辑器需要向用户显示一个内容,并在stdout上输出另一个内容。
但是,如果管道的其余部分不是太长/太糟糕,您可以使用Vim做以下事情:

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

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

:w !rest | of | pipeline

该命令在shell中运行rest | of | pipeline,并将当前缓冲区输入到其stdin中。您将在vim中看到该命令的输出,然后您将能够使用:q!放弃修改过的缓冲区并返回到shell。

nwsw7zdq

nwsw7zdq3#

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

command | vipe | another-command
xsuvu9jc

xsuvu9jc4#

如果你想使用一些随机编辑器(比如$EDITOR的值),你需要使用一个临时文件。大多数编辑器都不具备接受stdin上的整个文件并在编辑完成后将其写入stdout的功能。
有关创建临时文件的安全方法,请参见mktemp(或tempfile,在不太可能的情况下,您没有mktemp)。

3df52oht

3df52oht5#

试试看:

tmpfile=$(mktemp); command-one > $tmpfile && vim $tmpfile && command-two < $tmpfile && rm $tmpfile
fykwrbwg

fykwrbwg6#

如果有人想要#powershell而不是#bash的相同解决方案,

function Choose () {
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]]
        $Text
    )
    begin {
        $file = New-TemporaryFile
        $Text
    }
    process 
    {
        foreach ($line in $Text){
            $line >> $file
        }
    }
    end{
        start-process nvim $file -wait
        Get-Content $file
        Remove-Item $file 
    }
}

并使用它来编辑 *git稀疏 checkout 信息 *

function Git-Sparse-Checkout-Edit 
{
    git sparse-checkout list | Choose | git sparse-checkout set --stdin

}

我使用的编辑器是nvim,但应该可以和任何编辑器一起使用。如果你想知道为什么要 start-process,那么我真的不知道。如果我不这样做,终端会停止工作,变得没有React。

相关问题