使用 vim(搜索和替换)命令在脚本中搜索和替换多个字符串而不使用 sed?

使用 vim(搜索和替换)命令在脚本中搜索和替换多个字符串而不使用 sed?

创建天气降水文件的脚本是,

#!/bin/ksh

x=10
b=snow
c=rain
d=snow
e=hail
echo "$x,$b,$c,$d,$e" > weatherfile

exit 0

给定

3,8s/snow/dry/g

对于搜索和替换,在脚本中实现此功能的最佳方法是什么?

从指挥的角度来看有sed必要吗?

我的想法是以下应该有效:

sed 3,8s/snow/dry/g weatherfile

虽然sed不能用怎么办。我需要打开和关闭文件以及如何运行

:3,8s/snow/dry/g当文件打开时?如何实施?

答案1

您可以vim直接将命令与此处文档一起使用(这对于不规则的替换特别有用):

#!/bin/ksh
vim weatherfile <<EOF
:3,8s/snow/dry/g
:wq
EOF

答案2

您可以使用如下脚本完全在 shell 中完成此操作:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(我已经在 bash 中对此进行了测试,并且安德烈报告说它可以在 ksh 中工作,但不能在所有 POSIX 兼容版本中工作sh。)  它从标准输入读取行。它对行进行计数(使用line_num=0和 ,: $((line_num++)) 因为您要指定行号范围;如果删除该要求,则line_num可以删除引用的语句。条件测试

        if [[ line_num -ge 3  &&  line_num -le 8 ]]

表示“IF (line_num ≥ 3) AND (line_num ≤ 8)”,对应于范围3,8,即 3 到 8。(这对于 Unix 新手来说是一个困惑,他们希望3,8表示“3 和 8”,并且期望“3 到 8”表示为3-8— 即 Windows 中的打印对话框用于打印文档页面子集的约定。)

在该范围内的行上,它使用

        ${范围/图案/细绳

在将行写入标准输出之前,参数扩展的形式将“snow”替换为“dry”。超出范围的行将不加修改地写入。

这将更改范围内每行上“snow”的第一次出现(如果有)。要替换所有出现的情况,请使用${line//snow/dry}/在“snow”之前插入一个额外的字符)。

我不清楚你想要什么的大局。

  • 您可以将上述代码合并到现有脚本中。
  • 如果您修改了脚本(让我们称之为weather.sh)以写入标准输出而不是文件,那么您可以说

    ./weather.sh | ./do_substitute.sh > weatherfile
    
  • 如果您想以weatherfile与现在相同的方式创建,但随后更改它,您可以这样做

    ./do_substitute.sh < weatherfile > weatherfile.tmp
    mv weatherfile.tmp weatherfile
    

相关内容