[英]Bash script to copy from one line and replace another line with the copy
I am looking to write a bash script for something slightly more complicated than the usual find/replace via sed. 我正在寻找一个写bash脚本的工具,它比通过sed进行的普通查找/替换稍微复杂一些。 I have a book called bash Cookbook that I have been trying to glean some inspiration from but I am not getting very far. 我有一本叫做bash Cookbook的书,我一直在努力从中汲取一些灵感,但是我并没有走得太远。
Basically I am trying to write a script to update the version numbers in a bunch of maven pom.xml files automatically. 基本上,我试图编写一个脚本来自动更新一堆maven pom.xml文件中的版本号。 Here is the general setup I am looking at: 这是我正在查看的常规设置:
<!-- TEMPLATE:BEGIN
<version>@@VERSION@@</version>
-->
<version>1.0.0</version>
<!-- TEMPLATE:END -->
After running the script (with the new version number 1.0.1) I'd like the file to read this instead: 运行脚本(新版本号为1.0.1)后,我希望文件改为读取此内容:
<!-- TEMPLATE:BEGIN
<version>@@VERSION@@</version>
-->
<version>1.0.1</version>
<!-- TEMPLATE:END -->
So this would be in the actual release pom file, with 1.0.0 being the current version (and I am trying to replace it with 1.0.1 or something). 因此,这将在实际的发行pom文件中,当前版本为1.0.0(并且我尝试将其替换为1.0.1或其他名称)。 Obviously the version number will be changing so there isn't a good way to do a find/replace (since the thing you want to find is variable). 显然,版本号将发生变化,因此没有找到查找/替换的好方法(因为您要查找的内容是可变的)。 I am hoping to be able to write a bash script which can 我希望能够写一个bash脚本
I can sort of do some of this (writing out to a new file, doing replacement) using an ant script a la 我可以排序的做一些这样使用Ant脚本一拉(写出到一个新的文件,做更换)
<replace file="pom.xml">
<replacefilter token="@@VERSION@@" value="${version}"/>
</replace>
But I am not sure what the best ways to a.) delete the line with the old version or b.) tell it to copy the new line in the correct place are. 但是我不确定a。)删除旧版本的行或b。)告诉它在正确位置复制新行的最佳方法是什么。 Anyone know how to do this or have any advice? 有人知道该怎么做或有什么建议吗?
Assuming the new version number is in a shell variable $VERSION
, then you should be able to use: 假设新版本号在外壳变量$VERSION
,那么您应该可以使用:
sed -e '/<!-- TEMPLATE:BEGIN/,/<!-- TEMPLATE:END -->/{
s/<version>[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*<\/version>/<version>'$VERSION'<\/version>/
}'
Note that this ignores the template version line with @@VERSION@@
, but only matches a three-part version number that appears between the lines containing TEMPLATE:BEGIN and TEMPLATE:END, leaving everything else (including other lines containing a <version>...</version>
element) alone. 请注意,这会忽略带有@@VERSION@@
的模板版本行,但只会匹配出现在包含TEMPLATE:BEGIN和TEMPLATE:END的行之间的三部分版本号,其余所有内容(包括其他包含<version>...</version>
元素)。
You can decide how to do file overwriting (maybe your version of sed
is from GNU and it does that automatically on request with the -i
option), etc. You might also be able to use more powerful regular expression notations that lead to more compact matches. 您可以决定如何进行文件覆盖(也许您的sed
版本来自GNU,并且它会根据请求使用-i
选项自动执行此操作),等等。您还可以使用功能更强大的正则表达式表示法,从而使代码更紧凑火柴。 However, that should work on most versions of sed
without change. 但是,这应该可以在大多数版本的sed
使用。
The steps you outlined (1-3) read as if you do not actually care to perform the replacement in accordance to the templated rules defined within the comments. 您概述的步骤(1-3)看起来像您实际上并不在乎按照注释中定义的模板化规则执行替换一样。
As such, here is some code that behaves verbosely as you outlined: 因此,这是一些代码,其行为与您概述的一样:
#!/bin/bash
file=$1
newversion=$2
sed -i $file -e "s|<version>\([^@]*\)</version>|<version>$newversion</version>|"
Run it: 运行:
chmod +x yourscript.sh
./yourscript.sh filetoupdate.xml 1.0.1
use 5.010;
use strictures;
use Perl::Version qw();
use XML::LibXML qw();
my $dom = XML::LibXML->load_xml(location => 'pox.xml');
for my $node ($dom->findnodes('//version')) {
my $version = Perl::Version->new($node->textContent);
$version->inc_subversion;
$version->stringify;
$node->removeChildNodes;
$node->appendText($version);
};
say $dom->toString;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.