如何防止 sed 插入空格?
How can I prevent sed from inserting blanks?
我写这段代码是为了从一个文件中提取软件版本并在另一个文件中覆盖它:
newVersion=$(sed -r -n 's/<version>(.*-SNAPSHOT)<\/version>//p' sa-pom.xml)
find ./pom.xml -type f -exec sed -r -i -e "s/<version>(.*-SNAPSHOT)<\/version>/<version>${newVersion}<\/version>/g" {} \;
echo '<version>'$newVersion'</version>'
有效,但它在支持变量中放置一个 space,在目标文件中放置三个 space,分别生成以下输出:
<version> 0.19.6-SNAPSHOT</version>
<version> 0.19.6-SNAPSHOT</version>
这是 sa-pom.xml 文件的剪切版本:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my-group-id</groupId>
<artifactId>my-artifact-id</artifactId>
<version>0.19.9-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-project-name</name>
</project>
这是 pom.xml 文件的剪辑版:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>my-group-id</groupId>
<artifactId>my-parent-artifact-id</artifactId>
<version>${revision}</version>
</parent>
<artifactId>my-artifact-id</artifactId>
<version>0.19.8-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-project-name</name>
</project>
如何解决?
sed
并不是真的 在此处添加 任何空格,但它会捕获任何已经存在的空格,并将它们保留在替换中。但是,只需扩展您的正则表达式即可避免捕获任何空格。
newVersion=$(sed -n -r 's%.*<version>[[:space:]]*(.*-SNAPSHOT)</version>.*%%p' sa-pom.xml)
sed -r -i "s%<version>[[:space:]]*(.*-SNAPSHOT)</version>%<version>${newVersion}</version>%" pom.xml
echo "<version>$newVersion</version>"
在 <version>
之前添加 .*
会删除行中的前导空格(以及 <version>
标记之前的任何其他文本)。我还在 </version>
之后添加了 .*
到 trim 结束标记后的任何文本,只是为了保持这种健壮性。
在捕获之前添加 [[:space:]]*
确保捕获的表达式中不包含空格,因为正则表达式引擎将跳过尽可能多的内容,并且永远不需要从那里回溯以获得匹配项(如果它回溯,那是因为它根本找不到匹配项)。
如果这听起来太复杂,让我们更广泛地说明正则表达式引擎更喜欢最长的最左边的匹配,因此匹配捕获组之外的空格将它们排除在外。
find
在这里似乎完全是多余的。
您会注意到我还切换了 s%..%..%
定界符,以避免必须使用反斜杠转义斜杠。 /g
标志似乎也没有必要(除非你真的希望每行有多个匹配项,但是你不能在搜索中使用 .*
因为它会吃掉第一个匹配项和最后一个匹配项之间的所有文本).如果您的脚本仅包含一个字符串(并且不以破折号开头),则 -e
并不是必需的。最后,我修复了 echo
.
中的引号
这还是很脆弱的;理想情况下,使用 XML 感知工具从 XML 文件中解析值。
我写这段代码是为了从一个文件中提取软件版本并在另一个文件中覆盖它:
newVersion=$(sed -r -n 's/<version>(.*-SNAPSHOT)<\/version>//p' sa-pom.xml)
find ./pom.xml -type f -exec sed -r -i -e "s/<version>(.*-SNAPSHOT)<\/version>/<version>${newVersion}<\/version>/g" {} \;
echo '<version>'$newVersion'</version>'
有效,但它在支持变量中放置一个 space,在目标文件中放置三个 space,分别生成以下输出:
<version> 0.19.6-SNAPSHOT</version>
<version> 0.19.6-SNAPSHOT</version>
这是 sa-pom.xml 文件的剪切版本:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my-group-id</groupId>
<artifactId>my-artifact-id</artifactId>
<version>0.19.9-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-project-name</name>
</project>
这是 pom.xml 文件的剪辑版:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>my-group-id</groupId>
<artifactId>my-parent-artifact-id</artifactId>
<version>${revision}</version>
</parent>
<artifactId>my-artifact-id</artifactId>
<version>0.19.8-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-project-name</name>
</project>
如何解决?
sed
并不是真的 在此处添加 任何空格,但它会捕获任何已经存在的空格,并将它们保留在替换中。但是,只需扩展您的正则表达式即可避免捕获任何空格。
newVersion=$(sed -n -r 's%.*<version>[[:space:]]*(.*-SNAPSHOT)</version>.*%%p' sa-pom.xml)
sed -r -i "s%<version>[[:space:]]*(.*-SNAPSHOT)</version>%<version>${newVersion}</version>%" pom.xml
echo "<version>$newVersion</version>"
在 <version>
之前添加 .*
会删除行中的前导空格(以及 <version>
标记之前的任何其他文本)。我还在 </version>
之后添加了 .*
到 trim 结束标记后的任何文本,只是为了保持这种健壮性。
在捕获之前添加 [[:space:]]*
确保捕获的表达式中不包含空格,因为正则表达式引擎将跳过尽可能多的内容,并且永远不需要从那里回溯以获得匹配项(如果它回溯,那是因为它根本找不到匹配项)。
如果这听起来太复杂,让我们更广泛地说明正则表达式引擎更喜欢最长的最左边的匹配,因此匹配捕获组之外的空格将它们排除在外。
find
在这里似乎完全是多余的。
您会注意到我还切换了 s%..%..%
定界符,以避免必须使用反斜杠转义斜杠。 /g
标志似乎也没有必要(除非你真的希望每行有多个匹配项,但是你不能在搜索中使用 .*
因为它会吃掉第一个匹配项和最后一个匹配项之间的所有文本).如果您的脚本仅包含一个字符串(并且不以破折号开头),则 -e
并不是必需的。最后,我修复了 echo
.
这还是很脆弱的;理想情况下,使用 XML 感知工具从 XML 文件中解析值。