【问题标题】:Running vi within a bash script and executing vi commands to edit another file在 bash 脚本中运行 vi 并执行 vi 命令来编辑另一个文件
【发布时间】:2014-03-27 17:07:21
【问题描述】:

所以我制作了一个脚本,它从许多不同的文件中收集数据:

#!/bin/bash

mkdir DATAPOOL"$1"

grep achi *out>runner
grep treat *out>>runner

cat runner | grep Primitive *gout | grep '=   '|awk '{print $1,$6}' > CellVolume"$1".txt 
cat runner | grep ' c ' *gout | grep 'Angstrom   '|awk '{print $1,$3}' > Cellc"$1".txt 
cat runner | grep 'Final energy ' *gout |awk '{print $1,$5}' > CellEnergy"$1".txt

等等等等

cat runner |awk '{print "~/xtlanal",$1," > ",$1}' >runner2
vi runner2
:1,$s/gout:/xtl/
:1,$s/gout:/dat/
:wq

source runner2

grep Summary *dat | grep 'CAT-O  ' |awk '{print $1,$6}' > AVE_NaO_"$1".txt

mv *txt DATAPOOL"$1"

因此,在没有 vi 部分的情况下运行时,我最终得到了所有必需的文本文件,所以我知道这一切都有效。此外,当我使用 vi 命令运行它时,它只是在 vi 命令处停止运行,然后我可以手动输入 3 个命令,最终得到正确的结果。我正在努力解决的是我无法让 vi 自己运行命令,所以我可以在不同的目录中多次执行文件,而不必一次又一次地手动输入命令。

任何帮助将不胜感激。

干杯

【问题讨论】:

  • 看起来您正在尝试自动化 vi 的使用。也许如果您告诉我们1,$s/gout:/xtl/ 命令的作用,我们可以帮助您以更直接的方式进行操作。
  • 使用sed 而不是自动化vi 有什么问题?喜欢:sed -i -e 's/gout:/xtl/' runner2?
  • 是的,除了 vi 之外,还有多种方法可以编辑/删除/创建文件,这些文件可以在您的脚本中使用。你为什么不试试呢?
  • 我发现在脚本中运行 VI 的最佳方法是使用 vi runner2 -c ':1,$s/gout:/xtl/ :1,$s/gout:/dat/ :wq' 这使 vi 运行命令(只是替换文件的扩展名)。 -c 允许 vim 传递可执行命令。注意撇号是必需的。

标签: bash shell terminal editor vi


【解决方案1】:

类似这样的 bash 脚本:

#!/bin/bash
vi filename.txt -c ':g/^/m0' -c ':wq'

其中-c 执行命令。这里的命令是反转文本文件中的行。完成后,:wq 保存并退出。 (man vi 了解更多关于 -c 的信息)

如果你不想输入两次-c,你可以这样做:

vi -c "g/^/m0 | wq" filename.txt

【讨论】:

  • 知道如何使用 -c 'ESC KEY PRESS' 退出插入模式吗?
  • 嗨,据我所知,插入模式默认关闭 - 您可以在 .vimrc 文件中更改它:startinsert
【解决方案2】:

对于脚本编辑任务,您可以使用ed 代替vi:

ed runner2 <<'END'
1,$s/gout:/xtl/
1,$s/gout:/dat/
w
q
END

对于全局面向行的搜索和替换,sed 是一个不错的选择:

sed -i 's/gout:/xtl/; s/gout:/dat/' runner2

【讨论】:

  • +1,虽然我不明白替换 gout: 两次有什么意义,因为在第一次替换后,第二次将找不到它。无论如何,这似乎来自 OP,所以没有什么反对你的答案。
  • 我的假设是它不止一次出现在行中,第一个将被“xtl”替换,第二个被“day”替换——我没有仔细查看 OP 的代码.
  • 啊,是的,当然,虽然我真的不知道为什么会发生这一切,但无论如何,你的答案就是我所建议的(特别是 sed 方式)。简单的。 :) 注意:sed -i 在某些系统上需要一个额外的参数,告诉它要使用的备份文件后缀(即使它只是一个空的,例如在 Mac OS X 上)。
【解决方案3】:

在 VIM 上测试 - Vi IMproved 8.0(2016 年 9 月 12 日,2018 年 4 月 10 日 21:31:58 编译)

vi -c "g/^/m0 | wq" filename.txt 可能看起来有效,但实际上并没有!

键入 vi -c "g/^/m0 | wq" filename.txt 将导致 vi 在对文件进行任何重大更改之前写入并退出。 (在这种情况下使用管道将尝试逐行执行 wq 强制它在预期操作之前退出)

为了观看演示,请尝试在不带 q 的情况下输入它,看看它在逐行写入时有多慢:

vi -c "g/^/m0 | w" filename.txt

更有效的方法是像 B. Kocis 所说的那样使用 -c,或者使用 +。

正如 B. Kocis 所说:

#!/bin/bash
vi filename.txt -c ':g/^/m0' -c ':wq'

vi filename.txt +g/^/m0 +wq

【讨论】:

    猜你喜欢
    • 2017-02-09
    • 2013-10-26
    • 2023-04-08
    • 2021-09-09
    • 1970-01-01
    • 2010-10-31
    • 2013-05-03
    • 2014-10-19
    • 2023-04-06
    相关资源
    最近更新 更多