这是我的剧本:
#! /bin/bash
# C-band Edit
dqt='"'
str5="polarization=${dqt}2${dqt}"
for x in {3600..4200} do;
sed -i "/$str5.*$x/s/$x/$((x-600))/" satellites.xml
done我所要做的就是在所有在str5中都有satellites.xml的行中,用x-600替换为x-600,在3600到4200之间,但是上面的脚本给了我语法错误。
发布于 2022-05-06 04:00:12
我刚刚想到,您不是指字面字符串x-600,而是“从3600到4200之间的每个值中减去600”。在这种情况下,使用perl,而不是sed:
echo "$str5. foo bar 3200 3964 4155 4200 4255" |
perl -p -e "if (/$str5/) {s/3[6789]\d\d|4[01]\d\d|4200/A1-600/eg}"
polarization="2". foo bar 3200 3364 3555 3600 4255这使用perl的/e regex修饰符使右侧(D3-600)成为evaluated表达式。D4是一个perl变量,它包含匹配值,因此D5-600意味着从该值中减去600。
如果这是你真正想要的,我会在下面留下我最初的答案。还因为它有一些有用的解释,这些解释仍然与上面的perl答案有一定的关联。
与sed一样,perl有一个就地编辑的-i选项,这样您就可以将其直接应用到satellites.xml文件中。详情请参见man perlrun。
perl -i -p -e "if (/$str5/) {s/3[6789]\d\d|4[01]\d\d|4200/A8-600/eg}" satellites.xml还值得注意的是:在处理XML文件时,您可能应该使用XML解析器。幸运的是,perl有几个可供选择,例如XML::解析器或集合libxml-perl。
我没有您实际输入的示例,所以我编写了一个示例来演示哪些内容将被更改,哪些将不会:
str5='polarization="2"'
echo "$str5. foo bar 3500 3964 4155 4200 4255" |
sed -e "/$str5/ {s/3[6-9][0-9][0-9]/3-600/g; s/4[01][0-9][0-9]/4-600/g; s/4200/4-600/g}"
polarization="2". foo bar 3500 3-600 4-600 4-600 4255大致翻译为英文,即“如果当前行包含$str5 (polarization="2"),那么对其应用这三个s///操作”。
备注:
sed的一个运行中发生所有更改,而不是600个运行。s///操作来完成,方法是将最后两个操作合并为一个: sed -e "/$str5/ { s/3/3-600/g;S/4200/4600/g }“。3964、4155、4200发生了变化。3500和4255不是,它们超出了预期的范围。[0-9]不会像您在某些区域设置中所期望的那样工作(在该区域中还有其他字符)。我不知道具体是哪个地区,但我经常看到它被提到,以至于我知道不能完全依赖[0-9]。如果这影响到您,您可以使用[[:digit:]]而不是[0-9],或者使用perl -p而不是sed (因此您可以使用\d而不是[0-9])。同样适用于范围[6-9],使用[6789]代替。$str5变量中放入什么内容时要非常小心。因为它被插入到一个sed命令中,所以很容易破坏sed脚本(例如,如果$str5包含一个/,它将破坏/$str5/匹配)。sed不知道它的脚本部分来自shell变量,它看到的只是它被赋予运行的脚本。另外,通过sed作为正则表达式,整个字符串将是<#>interpreted --这意味着regex将不会被解释为文字字符,除非用\对它们进行转义。除非将.转义为\.,否则它将被解释为“任意字符”而不是文字点。发布于 2022-05-06 08:59:04
原则上,您的尝试是正确的,您没有在do之前用分号关闭列表,正如frabjous指出的:
for x in {3600..4200}; do但请注意,这将使您编辑601次文件“就位”,实际上创建和删除新文件的威胁每次你执行。
为了避免你可以
sed一些基本的数字理解,一次完成,这很有趣,但并不是很有用。python、perl或awk等数字的工具sed: #! /bin/bash
# C-band Edit
dqt='"'
str5="polarization=${dqt}2${dqt}"
sed -Ei "/$str5$x/{"$(for x in {36..41}; do echo -n "s/$x([0-9]{2})/$((x-6))\\1/;"; done)";s/4200/3600/;}" satellites.xml替换将生成sed脚本
s/36([0-9]{2})/30\1/;s/37([0-9]{2})/31\1/;s/38([0-9]{2})/32\1/;s/39([0-9]{2})/33\1/;s/40([0-9]{2})/34\1/;s/41([0-9]{2})/35\1/;s/4200/3600/https://unix.stackexchange.com/questions/701591
复制相似问题