如何在 shell 脚本中使用 vi 命令?
How can I use vi command in shell script?
我使用的是 CentOS 6.7
我想用 vi 打开 test.txt 并插入文本 "hihi"
然后保存并退出vi。
#! /bin/bash
vi test.txt << 'END'
i
hihi
press ESC
w
q
END
这样的结果
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: preserving files...
Vim: Finished.
我该如何解决?
创建或修改文本文件的方法有很多,范围从cat
、到sed
、到awk
、到ed
。不过,我假设您有充分的理由想要使用 vi
.
试试这个命令:
echo $'ihihi\E:x\n' | vi test.txt
在运行中,这看起来像:
$ echo $'ihihi\E:x\n' | vi test.txt
Vim: Warning: Input is not from a terminal
$ cat test.txt
hihi
我发现这种方法很脆弱:如果 vi
遇到错误情况,将看不到任何消息。
工作原理
我们需要 vi
才能看到转义字符。有很多方法可以做到这一点。我选择使用 bash 的 $'...'
字符串,因为它允许将转义输入为简单的两个字符串:\E
。我们使用的步骤是:
i
引入插入模式。
四个字符hihi
被输入缓冲区
退出,\E
,退出插入模式。
:x\n
退出并保存。
这么简单的事情你不需要使用 vi。您可以使用 echo
。例如:
echo "hihi" > test.txt
如果你真的想做一些更复杂的事情,post一些更多的细节。
从 bash 调用 vim:
vim test.txt +$'i\nhihi' +w +q
您可能还想查看 "ed"。那是一个类似于 vi 命令的编辑器,但它实际上被设计为从脚本中调用。
vi
是历史上旧编辑器 ex
的 visual 模式,是旧编辑器 ed
的扩展版本。您始终可以使用 ex
或 vi -e
.
恢复到旧的线路模式
那样的话,它只是从标准输入中读取,因此可以很容易地在 bash 脚本中使用。
这里是
ex test.txt << END
i
hihi
.
wq
END
(点用于在行模式下退出输入模式,如ed
)
使用 shell 中的 vi 命令是这样工作的:
vi -c "set fileformat=unix | wq" filename.txt
但是,这不适用于像 g 这样的命令。
你需要使用两个 -c 参数才能工作,例如:
vi -c g/^/m0 -c wq filename.txt
或
vi filename.txt -c g/^/m0 -c wq
编码愉快!
P.S。
在您使用的情况下:
vi test.txt +$'i\nhihi' +wq
这将在内存中的当前行之前插入!
例如,如果您之前使用此命令在第 20 行之前插入了“hihi”:
vi test.txt +20$'i\nhihi' +wq (insert hihi before line 20)
vi test.txt +20$'a\nhihi' +wq (insert hihi after line 20)
然后在没有指定数字的情况下键入将使用内存中的最后一个数字。
vi test.txt +$'i\nhihi' +wq (This command will now insert before line 20)
vi test.txt +$'a\nhihi' +wq (This command will now insert after line 20)
您必须通过指定新编号来重置内存中的行号:
vi test.txt +0$'i\nhihi' +wq (add hihi before line 0 to very top)
vi test.txt +0$'a\nhihi' +wq (add hihi after line 0 to very top)
vi test.txt +1$'i\nhihi' +wq (add hihi before line 1 to very top)
vi test.txt +1$'a\nhihi' +wq (add hihi after line 1 as line 2)
如果不知道 test.txt 中的最后行号,可以使用 wc 计算行数。
(在最后一行前添加hihi)
vi test.txt +$(wc -l < test.txt)$'i\nhihi' +wq
或
(在最后一行后添加 hihi)
vi test.txt +$(wc -l < test.txt)$'a\nhihi' +wq
我使用的是 CentOS 6.7
我想用 vi 打开 test.txt 并插入文本 "hihi" 然后保存并退出vi。
#! /bin/bash
vi test.txt << 'END'
i
hihi
press ESC
w
q
END
这样的结果
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: preserving files...
Vim: Finished.
我该如何解决?
创建或修改文本文件的方法有很多,范围从cat
、到sed
、到awk
、到ed
。不过,我假设您有充分的理由想要使用 vi
.
试试这个命令:
echo $'ihihi\E:x\n' | vi test.txt
在运行中,这看起来像:
$ echo $'ihihi\E:x\n' | vi test.txt
Vim: Warning: Input is not from a terminal
$ cat test.txt
hihi
我发现这种方法很脆弱:如果 vi
遇到错误情况,将看不到任何消息。
工作原理
我们需要 vi
才能看到转义字符。有很多方法可以做到这一点。我选择使用 bash 的 $'...'
字符串,因为它允许将转义输入为简单的两个字符串:\E
。我们使用的步骤是:
i
引入插入模式。四个字符
hihi
被输入缓冲区退出,
\E
,退出插入模式。:x\n
退出并保存。
这么简单的事情你不需要使用 vi。您可以使用 echo
。例如:
echo "hihi" > test.txt
如果你真的想做一些更复杂的事情,post一些更多的细节。
从 bash 调用 vim:
vim test.txt +$'i\nhihi' +w +q
您可能还想查看 "ed"。那是一个类似于 vi 命令的编辑器,但它实际上被设计为从脚本中调用。
vi
是历史上旧编辑器 ex
的 visual 模式,是旧编辑器 ed
的扩展版本。您始终可以使用 ex
或 vi -e
.
那样的话,它只是从标准输入中读取,因此可以很容易地在 bash 脚本中使用。
这里是
ex test.txt << END
i
hihi
.
wq
END
(点用于在行模式下退出输入模式,如ed
)
使用 shell 中的 vi 命令是这样工作的:
vi -c "set fileformat=unix | wq" filename.txt
但是,这不适用于像 g 这样的命令。
你需要使用两个 -c 参数才能工作,例如:
vi -c g/^/m0 -c wq filename.txt
或
vi filename.txt -c g/^/m0 -c wq
编码愉快!
P.S。 在您使用的情况下:
vi test.txt +$'i\nhihi' +wq
这将在内存中的当前行之前插入!
例如,如果您之前使用此命令在第 20 行之前插入了“hihi”:
vi test.txt +20$'i\nhihi' +wq (insert hihi before line 20)
vi test.txt +20$'a\nhihi' +wq (insert hihi after line 20)
然后在没有指定数字的情况下键入将使用内存中的最后一个数字。
vi test.txt +$'i\nhihi' +wq (This command will now insert before line 20)
vi test.txt +$'a\nhihi' +wq (This command will now insert after line 20)
您必须通过指定新编号来重置内存中的行号:
vi test.txt +0$'i\nhihi' +wq (add hihi before line 0 to very top)
vi test.txt +0$'a\nhihi' +wq (add hihi after line 0 to very top)
vi test.txt +1$'i\nhihi' +wq (add hihi before line 1 to very top)
vi test.txt +1$'a\nhihi' +wq (add hihi after line 1 as line 2)
如果不知道 test.txt 中的最后行号,可以使用 wc 计算行数。
(在最后一行前添加hihi)
vi test.txt +$(wc -l < test.txt)$'i\nhihi' +wq
或
(在最后一行后添加 hihi)
vi test.txt +$(wc -l < test.txt)$'a\nhihi' +wq