shell 如何使用sed删除嵌套括号中的多个括号?

a6b3iqyw  于 2022-11-16  发布在  Shell
关注(0)|答案(4)|浏览(319)

我想做一个用shell编程编辑文件的程序代码
算术展开式$(())′中有命令′ Remove ${},我在实现时遇到问题。
我将编写下面的bash shell代码

计数=$((${计数} + ${计数123}))

计数=$((计数+计数123))
我想删除算术扩展括号中的命令替换括号

我试着用这个正则表达式:
sed -Ei 's/(\$\(\()([^\)]*?)\$\{([^\}]+?)\}(.*?)(\)\))/\1\2\3\4\5/g' $file
但是,它只找到了一个最长的匹配项。(即使在匹配项之前还有另一个匹配项)
如果你想看到可视化的正则表达式,点击这个链接visualized image
结果表明:
计数=$((${计数} +计数123))
如何删除嵌套括号中的内部括号?(我应该只使用awk或sed,但如果这可能是不可能的,使用其他bash命令也没关系)

工程示例:

s=$(( ${s} ** 2 ))s=$(( s ** 2 ))
sum=$(( ${a} + ${b} ))sum=$(( a + b ))
echo $(( (${var} * ${var2}) / ${var3} ))echo $(( (var * var2) / var3 ))
echo ${d} $((${t1} + ${t2})) ${e}echo ${d} $(( t1 + t2 )) ${e}
:我的示例输入文件(它的用途无关紧要)

#! /bin/bash

cnt=0
cnt123=1
for filename in *
do
        fname=$(basename $filename)
        cname=$(echo $fname | tr A-Z a-z)
        if [ "$fname" !=  "$cname" ] 
        then
                if [ -e "$cname" ]
                then 
                   echo "$cname already exists"
                   exit 1
                fi
                echo "$fname is renamed $cname"
                mv $fname $cname
                cnt=$(( ${cnt}+ ${cnt123} ))
        fi
done
echo "Total count: $cnt"
exit 0
fruv7luv

fruv7luv1#

由于sed/awk正则表达式和相关函数的开发不是一件容易的事情,请允许我展示一个perl解决方案,尽管您的问题中没有标记perl

perl -i -pe 's/(?<=\$\(\().+?(?=\)\))/ $_ = $&; s#\$\{(.+?)}#$1#g; $_ /ge' "$file"

输入文件示例:

s=$(( ${s} ** 2 ))
sum=$(( ${a} + ${b} ))
echo $(( (${var} * ${var2}) / ${var3} ))
echo ${d} $((${t1} + ${t2})) ${e}

修改后的结果:

s=$(( s ** 2 ))
sum=$(( a + b ))
echo $(( (var * var2) / var3 ))
echo ${d} $((t1 + t2)) ${e}
  • perl替换s/pattern/expression/e将匹配的pattern替换为perl expression,而不是字面(或固定)替换。
  • (?<=\$\(\().+?(?=\))匹配前面是$((后面是))的子字符串。那么匹配的子字符串将是$(( .. ))中的内容。perl变量$&被分配给它。
  • 表达式$_ = $&; s#\$\{(.+?)}#$1#g; $_是一个perl代码,用于从上面匹配的子字符串中删除成对的${}。分隔符#后面的g选项的工作方式与sed相同。
g0czyy6m

g0czyy6m2#

根据上下文,您可能希望将匹配范围限制为仅字母数字字符

sed -Ei.bak 's/\$\{([[:alnum:]]+)\}/\1/g'

以避免无意中匹配其他内容。

iszxjhcz

iszxjhcz3#

使用sed

$ sed -Ei.bak 's/\$\{([^}]*)}/\1/g' input_file
cnt=$(( cnt + cnt123 ))
mf98qq94

mf98qq944#

printf="cnt=\$(( \${cnt} + \${cnt123} ))" | tr -d '{' | tr -d '}'

我在这里使用printf是因为它比echo更值得信任。确保你转义了$,否则你会得到一个错误,因为bash试图解释变量。

相关问题