创建天气降水文件的脚本是,
#!/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