如何使用 sed 将字符串中的多个模式替换为不同的模式

如何使用 sed 将字符串中的多个模式替换为不同的模式

我想将一行中的多个数字替换为不同的值。例如,在字符串中"uncertainty = { 0.01 , 0.01 }"它应该替换为string "uncertainty = { 0.2 , 0.2 }"

问题是这些行出现在数百个文件中,并且括号内的数字数量各不相同。

它可能是:

"uncertainty = {  0.1 , 0.1, 0.1 }"

为了

"uncertainty = {  0.3 , 0.3, 0.3 }"

或者

"uncertainty = {  0.1 , 0.1, 0.1 , 0.1, 0.1, 0.1}"

为了

"uncertainty = {  0.3 , 0.3, 0.3 , 0.3, 0.3, 0.3}

等等,我必须把它们全部替换掉​​。

我不明白如何使用 sed 来做到这一点。

答案1

使用正则表达式。将花括号内的一项转换为正则表达式,例如:

[0-9]\.[0-9]1

这个表达式的意思是“一个数字,一个句号,一个数字,一个一”。如果格式始终一致,则通过 sed 只会替换“0.01”的实例。终端截图

还有其他工具也可以满足这些需求,例如awktr,但您仍需要使用正则表达式来替换它们。要批量替换这样的数字,您可以将该“1”替换为另一个[0-9][1-3]以指定 1-3 范围内的数字。

有关正则表达式的更多信息,请参阅雷克塞格。它们极大地扩展了几乎所有文本处理实用程序的实用性。

答案2

我读了关于 awk 的文章,结果发现它解决了我一半的问题:遍历与给定字符串匹配的字符串子字符串。由于 awk 有一些限制,我使用 sed 来清理混乱,例如,其中 v1 和 v2 通过调用此代码的 shell 脚本传递

awk 部分:

{
    found = match($0,"uncertainty")
    i = 4
    if (found) {
    while ( i < NF){
        if ($i = v1) {
          $i = v2
        }
        i = i + 2
    }
    print "        " $0 
    }
    else
    {
    print $0
    }
}

外壳部分:

#!/bin/bash

# Check if directory already exists,

#!/bin/bash

# Check if directory already exists,

bitSizeDir="$1"
value1="$2"
value2="$3"

_mydir="$(pwd)"
find $bitSizeDir/ -type f  > Files;
while read line; do
    folder=`dirname "$line"`
    file=`basename "$line"`
    if [ "$file" = "input.c" ] ; then
    awk -v v1=$value1 -v v2=$value2 -f changeValues.awk $line > input.new
    mv input.new $folder
    cd $folder
    rm $file
    mv input.new input.c
    sed -i '' "s/$3 , \}/ \} /g" input.c
        cd $_mydir
    fi
done < Files
rm Files

相关内容