如何在 bash 中正确执行‘vim $(grep -rli pattern | sed 's/\(.*\)/"&"/')’?

如何在 bash 中正确执行‘vim $(grep -rli pattern | sed 's/\(.*\)/"&"/')’?

我正在尝试使用 vim 编辑包含与正则表达式匹配的文本的文件,并在 bash 中使用以下命令来执行此操作:

vim $(grep -rli pattern | sed 's/\(.*\)/"&"/')

grep我将命令的输出通过管道传输sed到包含空格的文件名中。但是,它不起作用:包含空格的文件名不会被 vim 使用此命令打开。

这让我很困惑,因为当我执行

echo $(grep -rli pattern | sed 's/\(.*\)/"&"/')

文件名被正确引用。

那么,我必须做哪些改变才能让 vim 打开带有空格的文件?

答案1

启动新进程的系统调用需要如下字符串列表:

  1. vim
  2. /path/to/file
  3. ./path to a file with spaces/foo

请注意,第三项周围没有引号 - 这些字符串已被逐项列出,系统将把它作为整个传递给 vim。

引号不是为 vim 或操作系统而设的。它们是为 shell 而设的,因为您输入的是单个字符串形式的命令。shell 随后必须将其拆分为项目,因此它需要知道哪些空格是项目分隔符,哪些是项目的一部分。

$(…)在对引号进行求值后进行扩展并生成不同的项目:不是,而是 ,,,其中项目内有vim引号,但以空格作为分隔符。file namevim"filename"

这些“物品”实际上被称为参数, 顺便一提。

解决方案是使用xargs:一个程序,从标准输入中获取行并将它们作为参数附加到给定的命令。

grep -rli pattern | sed 's/\(.*\)/"&"/' | xargs vim

相关内容