简体   繁体   English

Bash脚本从一行复制,然后用副本替换另一行

[英]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脚本

  1. replace @@VERSION@@ with the actual version number 用实际版本号替换@@ VERSION @@
  2. delete the current version line 删除当前版本行
  3. write the updated version line on the line before the TEMPLATE:END (while preserving the @@VERSION@@ in the file - possibly do this by writing template out to a temp file, doing replacement, then back in?) 在TEMPLATE:END之前的行上写入更新的版本(在文件中保留@@ VERSION @@的同时-可以通过将模板写到临时文件中进行替换,然后再返回来完成此操作)

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.

相关问题 Bash脚本-将文件的最后一行复制到另一个文件 - Bash script - copy the last line of files to another files 从命令行参数使用bash脚本复制多个文件? - Copy multiple files with bash script from command line arguments? 复制一行并在bash linux中粘贴5次 - Copy one line and paste 5 times in bash linux Linux - 将一行从一个文件复制到多个其他文件的脚本 - Linux - script to copy a line from one file to multiple other files 使用awk将特定行号从一个文件复制到另一文件的特定行号 - to copy specific line numbers from one file to specific line numbers of another file using awk Bash / ZSH - 如何从特定行复制到文件末尾,然后粘贴到另一个文件的第 1 行,同时保留该文件中的所有文本 - Bash / ZSH - How to copy from a specific line to the end of a file, then paste at line 1 of another file whist preserving all text in that file Linux 在 bash/python 脚本中将下一个“n”个文件从一个文件夹复制到另一个文件夹 - Linux copy next 'n' number of files from one folder to another in bash/python script Bash 如果存在另一行则替换行 - Bash replace line if another line exist 使用 vim 复制一个文件的内容并将其插入另一个文件的特定行 - Copy the content of one file and insert it in particular line in another using vim 如何在没有外壳(命令行)访问的情况下将表从一个数据库复制到同一服务器上的另一个数据库? - How can I copy a table from one database to another on the same server without shell (command line) access?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM