我有一个包含
的字符串fastcgi_cache_path /var/run/nginx-cache15 levels=1:2 keys_zone=MYSITEP:100m inactive=60m;
此脚本的目标之一是根据先前文件中的值find增加 nginx-cache 两位数。为此,我使用了这段代码:
# Replace cache_path
PREV=$(ls -t /etc/nginx/sites-available | head -n1) #find the previous cache_path number
CACHE=$(grep fastcgi_cache_path $PREV | awk '{print $2}' |cut -d/ -f4) #take the string to change
SUB=$(echo $CACHE |sed "s/nginx-cache[0-9]*[0-9]/&@/g;:a {s/0@/1/g;s/1@/2/g;s/2@/3/g;s/3@/4/g;s/4@/5/g;s/5@/6/g;s/6@/7/g;s/7@/8/g;s/8@/9/g;s/9@/@0/g;t a};s/@/1/g") #increment number
sed -i "s/nginx-cache[0-9]*/$SUB/g" $SITENAME #replace number
也许不那么优雅,但它有效。
另一个目标是增加所有出现的 MYSITE x 的最后一个字母( MYSITEP ,在这种情况下,应该成为MYSITE Q ,在MYSITE P 等之后等,一旦MYSITE Z 将到达,请添加另一个字母,如MYSITE AA , MYSITE AB 等等。
我想的是:
sed -i "s/MYSITEP[A-Z]*/MYSITEGG/g" $SITENAME
但它无法正常工作,因为MYSITEGG是一个静态值,无法使用。 如何计算最后一个字母,将其递增到下一个字母,一旦到达最后一个Z字母,再添加一个字母?
谢谢!
答案 0 :(得分:4)
Perl的自动增量将按照您描述的方式处理字母和数字
我们也可以整理你的nginx-cache
增量,同时我们也会这样做
我假设SITENAME
包含要修改的文件的名称?
看起来像这样。我必须将捕获$1
分配给普通变量$n
以增加它,因为$1
是只读的
perl -i -pe 's/nginx-cache\K(\d+)/ ++($n = $1) /e; s/MYSITE\K(\w+)/ ++($n = $1) /e;' $SITENAME
如果您愿意,可以在一次替换中完成,例如
perl -i -pe 's/(?:nginx-cache|MYSITE)\K(\w+)/ ++($n = $1) /ge' $SITENAME
答案 1 :(得分:2)
注意:下面的解决方案是不必要的复杂,因为正如Borodin's helpful answer所示(以及@ stevesliva对此问题的评论), Perl 直接支持按照问题中描述的方式按字母顺序递增字母,方法是将++
运算符应用于包含字母(序列)的变量; e.g:
$ perl -E '$letters = "ZZ"; say ++$letters'
AAA
下面的解决方案仍然是一个值得关注的展示,展示了如何从shell中利用Perl的功能,展示了如下技术:
s///e
确定带表达式的替换字符串。split //, "...."
)ord
和chr
函数来获取char。的代码点,并将(n递增的)代码点转换回char。x
运算符)$chars[-1]
)@chars[0..$#chars-1]
) perl
解决方案(实际上是++
可以直接执行的重新实施):
perl -pe 's/\bMYSITE\K([A-Z]+)/
@chars = split qr(), $1; $chars[-1] eq "Z" ?
"A" x (1 + scalar @chars)
:
join "", @chars[0..$#chars-1], chr (1 + ord $chars[-1])
/e' <<'EOF'
...=MYSITEP:...
...=MYSITEZP:...
...=MYSITEZZ:...
EOF
的产率:
...=MYSITEQ:... # P -> Q
...=MYSITEZQ:... # ZP -> ZQ
...=MYSITEAAA:... # ZZ -> AAA
您可以使用perl
的{{1}}选项将输入文件替换为结果
(-i
)。
正如Borodin的回答所示,单独使用perl -i -pe '...' "$SITENAME"
来解决问题中的所有任务并不困难。
perl
函数的s
选项允许使用Perl 表达式来确定替换字符串,从而实现复杂的替换:
/e
引用表达式中的当前$1
后缀。
MYSITE
将后缀拆分为字符数组。
@chars = split qr(), $1
测试最后一个后缀是否为char。是$chars[-1] eq "Z"
如果是这样的话:后缀会被所有Z
替换,并附加A
个附加内容
(A
)。
否则:最后一个后缀char。被替换为字母中的以下字母
("A" x (1 + scalar @chars)
)