如何替换匹配后的单词?

时间:2014-03-31 11:49:49

标签: regex performance bash optimization

我有这段代码来替换文件中的单词:

function replace_str {
    echo "${1//${2}/${3}}"
}

myfile=$(cat input.txt)
myfile=$(replace_str "$myfile" 'banana' 'stackoverflow')
echo "$myfile"

然后,在input.txt中使用此内容:

banana
poop
poop
poop
banana
START123
poop
banana
banana
poop
START 6yu
poop
banana

结果如下:

stackoverflow
poop
poop
poop
stackoverflow
START123
poop
stackoverflow
stackoverflow
poop
START 6yu
poop
stackoverflow

我正在寻找的是替换第一个banana匹配后的所有^START.*字。这是所需的输出:

banana
poop
poop
poop
banana
START123
poop
stackoverflow
stackoverflow
poop
START 6yu
poop
stackoverflow

最有效的方法是什么?我想在剪切文件,替换它,并再次合并,但我认为不是一个好主意。

2 个答案:

答案 0 :(得分:3)

使用sed

sed '/^START.*/,${s/banana/stackoverflow/g}' inputfile

这会将banana替换为stackoverflow,从以START开头的行开头直到文件末尾。

它产生:

banana
poop
poop
poop
banana
START123
poop
stackoverflow
stackoverflow
poop
START 6yu
poop
stackoverflow

答案 1 :(得分:2)

对脚本的最快更改可能只是循环遍历文件。像

这样的东西
#!/bin/bash
function replace_str {
    echo "${1//${2}/${3}}"
}

match="START"
found=
while read -r line; do
  [[ $line =~ ^"$match" ]] && found=:
  [[ -n $found ]] && echo "$(replace_str "$line" 'banana' 'stackoverflow')" || echo "$line"
done < input.txt

示例输出

> ./abovescript
banana
poop
poop
poop
banana
START123
poop
stackoverflow
stackoverflow
poop
START 6yu
poop
stackoverflow