Bash 用awk或sed替换并增加字母和数字
我有一个包含Bash 用awk或sed替换并增加字母和数字,bash,perl,nginx,awk,sed,Bash,Perl,Nginx,Awk,Sed,我有一个包含 fastcgi_cache_path /var/run/nginx-cache15 levels=1:2 keys_zone=MYSITEP:100m inactive=60m; 此脚本的目标之一是基于在上一个文件中找到的值,将nginx缓存增加两位数。为此,我使用了以下代码: # Replace cache_path PREV=$(ls -t /etc/nginx/sites-available | head -n1) #find the previous cache_pat
fastcgi_cache_path /var/run/nginx-cache15 levels=1:2 keys_zone=MYSITEP:100m inactive=60m;
此脚本的目标之一是基于在上一个文件中找到的值,将nginx缓存增加两位数。为此,我使用了以下代码:
# 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
也许不那么优雅,但它很管用
另一个目标是增加MYSITEx(在这种情况下,MYSITEP应该成为MYSITEQ,在MYSITEp,等等之后。一旦达到MYSITEZ,添加另一个字母,比如MYSITEAA,MYSITEAB,等等
我的想法是:
sed -i "s/MYSITEP[A-Z]*/MYSITEGG/g" $SITENAME
但它不能工作,因为MYSITEGG是一个静态值,不能使用。
如何计算最后一个字母,将其递增到下一个字母,一旦到达最后一个Z字母,再添加一个字母
谢谢!注意:下面的解决方案是不必要的复杂,因为正如所示(以及@stevesliva对所暗示问题的评论),Perl直接支持以问题中描述的方式,通过对包含字母(序列)的变量应用
++
运算符,按字母顺序递增字母;例如:
下面的解决方案可能仍然是一个有注释的展示,展示了如何从shell中利用Perl的能力,展示了以下技术:
- 使用
确定表达式的替换字符串s///e
- 将字符串拆分为字符数组(
)拆分//,“…”
- 使用
和ord
函数获取字符的码点,并将(n递增的)码点转换回字符chr
- 字符串复制(
operator)x
- 数组索引和切片:
- 获取数组的最后一个元素(
)$chars[-1]
- 获取数组中除最后一个元素以外的所有元素(
)@chars[0..$#chars-1]
- 获取数组的最后一个元素(
一个
perl
解决方案(实际上是++
可以直接做的事情的重新实现):
perl-pe的/\bMYSITE\K([A-Z]+)/
@chars=拆分qr(),$1;$chars[-1]eq“Z”?
“A”x(1+标量@字符)
:
加入“”@chars[0..$#chars-1],chr(1+ord$chars[-1])
/e'Perl的自动增量将以您描述的方式处理字母和数字
我们还可以整理一下您的nginx缓存
增量
我假设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
Perl增加字母。我建议您需要Perl-p-e
解决方案。如果您愿意,可以添加标签。用单个awk脚本替换长时间运行的grep | sed | awk | sed
可能更容易实现,而无需学习新语言。一般来说,如果您使用awk,您应该需要grep
或sed
在同一管道中的使用非常少,而且非常少。但在这种特殊情况下,Perl似乎很适合,因为它支持OP开箱即用描述的行为。您还可以使用带有字母或零填充整数的。
运算符。('a'..'Z'
)运算符中隐藏了很多字符串操作功能,您可能没有想到。感谢大家提供了出色的解决方案!我尝试了@Borodin的解决方案,效果非常好!哇!这是一个非常好的解决方案!所有内容都在同一行中!效果非常好。非常感谢@Borodin!!
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