如何在bash中将命令的行输出用作单独的文件名?

时间:2013-12-18 19:08:21

标签: bash shell vim command-line output

我正在尝试干净利落,没有错误/怪癖,在vim文本编辑器中通过命令行打开多个文件。我使用bash作为我的shell。具体来说,我想打开当前工作目录中的前23个文件。我最初的命令是:

$ ls | head -23 | xargs vim

但是当我这样做时,我会在所有文件打开之前收到以下错误消息:

  

Vim:警告:输入不是来自终端

在vim退出后终端中没有显示新文本。我不得不盲目地做一个reset以获得一个正常的终端,除了开一个新终端。

这似乎在这里讨论:using xargs vim with gnu screen和:Why does "locate filename | xargs vim" cause strange terminal behaviour?

自从警告发生以来,xargs似乎与vim禁止。 (除非你使用子shell和输入/输出重定向做一些复杂的事情,我不太常感兴趣作为常用命令。并使用别名/函数...... meh。)

解决方案似乎是使用bash的命令替换。所以我试过了:

$ vim $(ls | head -23)

但文件中有空格和括号,格式如下:

surname, firstname(email).txt

那么shell然后做什么,也就是xarg情况下的结果,提供surname,firstname(email).txt作为两个单独的命令参数,让我在vim中至少有两倍的数量我想要打开的文件, none 实际想要打开的文件。

所以,我想我需要以某种方式转义文件名。我试着引用命令:

$ vim "$(ls | head -23)"

然后shell连接替换的整个输出,并提供 作为单个命令参数,所以我留下了一个超长文件名,这也不是我想要的。< / p>

我还尝试使用-exec的{​​{1}},-print-print0-printf选项,使用bash中的数组进行各种操作,可能还有一些我不记得的事情。我现在不知所措。

如何使用来自命令的文件名作为单独的命令参数 shell引用,以便它们实际起作用?

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

这是一个基于阵列的解决方案:

fileset=(*)
vim "${fileset[@]:0:23}"

答案 1 :(得分:1)

xargs -a <(ls | head -23) -d '\n' vim

-a告诉xargs从命名文件而不是stdin读取参数。 <(...)让我们传递ls / head管道的输出,其中包含文件名。