Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 用awk或sed替换并增加字母和数字_Bash_Perl_Nginx_Awk_Sed - Fatal编程技术网

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
    chr
    函数获取字符的码点,并将(n递增的)码点转换回字符
  • 字符串复制(
    x
    operator)
  • 数组索引和切片:
    • 获取数组的最后一个元素(
      $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