假设我有以下目录结构:
~/tmp$ ls edit.d/
1.t 2.t 3.t
和这样的文件:
~/tmp$ cat edit.list
edit.d/1.t
edit.d/2.t
edit.d/3.t
我想逐行阅读edit.list
文件,每个文件对应于上面显示的目录中一个文件的路径,并在vim中打开文件。到目前为止我已经尝试了
while read line; do vim -o $line; done <edit.list
和
cat edit.list | while read line; do vim -o $line; done
但它们都不起作用。返回的错误消息是
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.
我怀疑这与vim期望其stdin与其控制终端相同,但不确定如何修复它。
此命令
while read line; do cat $line | vim - ; done <edit.list
显示文件内容,但由于它是stdin
上的管道传输,因此无法保存修改。
一个糟糕的解决方法是使用此命令
while read line; do echo $line | vim - ; done <edit.list
以文件路径作为内容打开vim,然后使用fg
或<c-w>g
打开要编辑的实际文件。
这项任务是否有更好的解决方案,最好是一个班轮?
答案 0 :(得分:4)
当您重定向循环的标准输入时,vim
也会将其作为标准输入继承。改为使用不同的文件描述符。
while IFS= read -r <&3 line; do vim -o "$line"; done 3< edit.list
现在vim
仍然使用终端进行标准输入,虽然它也从while
循环继承了文件描述符3,但它并没有尝试实际读取它。
答案 1 :(得分:1)
你真的不需要循环。命令替换可以减少输入的工作:
$ vim -o `< edit.list`
或:
$ vim -o $(< edit.list)
答案 2 :(得分:0)
问题在于您已经覆盖了vim
的标准输入,而不仅仅是while循环。您可以通过明确告诉vim
从控制终端/dev/tty
接收其标准输入来解决此问题:
while read line; do vim "$line" < /dev/tty; done < edit.list