Bash:将所有参数完全按原样传递给函数,并在每个参数上添加一个标记

Mil*_*les 1 regex unix vim bash

这似乎是一个相对基本的问题,但经过一个小时的搜索,我无法在任何地方找到它.许多(有很多!)类似的问题似乎没有达到目的.

我正在写一个脚本("vims")在类似sed的模式下使用vim(所以我可以在流输入上调用普通的vim命令而不实际打开vim),所以我需要将每个参数传递给vim,并带有" - c"前面的旗帜.还有许多字符需要转义(我需要传递正则表达式),因此SO上的一些常用方法不起作用.

基本上,当我写:

cat myfile.txt | vims ':%g/foo/exe "norm yyPImyfile: \<esc>\$dF,"' ':3p'
Run Code Online (Sandbox Code Playgroud)

这是两个在stdout上运行的命令行vim参数,我需要将这两个单引号参数完全按照它们的方式传递给我的函数vims(),然后用一个-c标志标记它们,所以它们被解释为命令VIM.

这是我到目前为止所尝试的:

vims() {                                                                            
    vim - -nes -u NONE -c '$1' -c ':q!' | tail -n +2              
}   
Run Code Online (Sandbox Code Playgroud)

这似乎适用于单个命令.没有字符被转义,并且"-c"标志就在那里.

然后,使用经常复制的问答,"$@"诀窍,我试过:

vims() {
    vim - -nes -u NONE $(for arg in "$@"; do echo -n " -c $arg "; done) -c ':q!' | tail -n +2
}
Run Code Online (Sandbox Code Playgroud)

这似乎打破了我传递的每个字符串中的空格,所以不起作用.我也尝试了一些printf命令的变体,正如其他问题中所建议的那样,但这与vim命令序列有奇怪的交互.我在永久编辑测试循环中尝试了许多其他不同的反斜杠引用组合,但总是在我的方法中找到了一个怪癖.

我错过的命令序列是什么?

Joh*_*ica 5

一次添加一个数组的所有参数,然后通过适当的引用将整个数组传递给vim,以确保正确保留空格.

vims() {
    local args=()

    while (($# > 0)); do
        args+=(-c "$1")
        shift
    done

    vim - -nes -u NONE "${args[@]}" -c ':q!' | tail -n +2
}
Run Code Online (Sandbox Code Playgroud)

根据经验,如果你发现自己试图逃避事情,添加反斜杠,使用printf等等,你可能会走错路.小心使用引用和数组将涵盖大多数情况.