Regex 更新pom文件中标记之间文本的Bash脚本?
我用谷歌搜索了一下,但找不到具体的答案。Regex 更新pom文件中标记之间文本的Bash脚本?,regex,sed,pom.xml,Regex,Sed,Pom.xml,我用谷歌搜索了一下,但找不到具体的答案。 我有一个带有以下标记的pom.xml文件 <properties> <rpm.release>10</rpm.release> </properties> 10 然后我有一个脚本,它在标签之间寻找标签,这很有效 update_rpm_release_in_pom() { BUILD_NUM=$1 POM_FILE="./template/iptools/pom.xml" BEGIN
我有一个带有以下标记的pom.xml文件
<properties>
<rpm.release>10</rpm.release>
</properties>
10
然后我有一个脚本,它在标签之间寻找标签,这很有效
update_rpm_release_in_pom()
{
BUILD_NUM=$1
POM_FILE="./template/iptools/pom.xml"
BEGIN_PROPERTIES="n"
# Look for the <rpm.release> tag in the <properties>
# and update with with passed-in build_num
cat $POM_FILE | while read LINE
do
case $BEGIN_PROPERTIES in
n) # <property> tag not found yet
if [[ "$LINE" == *\<properties\>* ]]; then
BEGIN_PROPERTIES="y"
fi
continue
;;
y) # <property> tag found
if [[ "$LINE" == *\</properties\>* ]]; then
# </property> tag found, stop searching
break
fi
if [[ "$LINE" == *rpm.release* ]]; then
# Update value
####################################
# How do I update value??????
####################################
break
fi
;;
esac
done
}
# Call above function
update_rpm_release_in_pom 11
更新\u pom()中的\u rpm\u release\u
{
BUILD_NUM=$1
POM_FILE=“./template/iptools/POM.xml”
BEGIN_PROPERTIES=“n”
#在地图上寻找标签
#并使用传入的build_num进行更新
cat$POM_文件|在读取行时
做
案例$BEGIN\u中的属性
n) #尚未找到标签
如果[[“$LINE”==*\*];则
开始_PROPERTIES=“y”
fi
持续
;;
y) #找到标签
如果[[“$LINE”==*\*];则
#已找到标记,请停止搜索
打破
fi
如果[[“$LINE”==*rpm.release*];则
#更新值
####################################
#如何更新值??????
####################################
打破
fi
;;
以撒
完成
}
#调用上述函数
更新pom 11中的rpm版本
我应该在“#如何更新值??”中输入什么?因此,当我运行脚本时,pom.xml现在已经
<properties>
<rpm.release>11</rpm.release>
</properties>
11
谢谢。你可以用
[[ $LINE =~ ^([^>]+>)([0-9]+)(.*) ]] && printf -v LINE "%s%d%s" \
"${BASH_REMATCH[1]}" \
$(( ${BASH_REMATCH[2]} + 1 )) \
"${BASH_REMATCH[3]}"
是由=~
运算符设置的数组,用于将值存储在括号内
它只是更新了线路。我会使用我最喜欢的命令行xml工具完全重写它:
update_rpm_release_in_pom() {
local f=pom.xml
# get the current value
local current=$(xmlstarlet sel -t -v '/properties/rpm.release' $f)
local new=$(( current + 1 ))
# update the xml with the new value and save it
xmlstarlet ed -u '/properties/rpm.release' -v $new $f > $f.$new &&
mv $f $f.$current &&
mv $f.$new $f
}
你可以用
[[ $LINE =~ ^([^>]+>)([0-9]+)(.*) ]] && printf -v LINE "%s%d%s" \
"${BASH_REMATCH[1]}" \
$(( ${BASH_REMATCH[2]} + 1 )) \
"${BASH_REMATCH[3]}"
是由=~
运算符设置的数组,用于将值存储在括号内
它只是更新了线路。我会使用我最喜欢的命令行xml工具完全重写它:
update_rpm_release_in_pom() {
local f=pom.xml
# get the current value
local current=$(xmlstarlet sel -t -v '/properties/rpm.release' $f)
local new=$(( current + 1 ))
# update the xml with the new value and save it
xmlstarlet ed -u '/properties/rpm.release' -v $new $f > $f.$new &&
mv $f $f.$current &&
mv $f.$new $f
}
由于问题被标记,我认为
awk
将是一个有效的选择
在这种情况下,您可以在awk
中处理pom文件,将结果保存在tmpfile中,并用修改后的版本覆盖原始文件:
#!/bin/sh
# error function
error(){
echo -e >&2 "error: $@"
exit 1
}
update_rpm_release_in_pom()
{
#################
# set constants #
#################
POM_FILE="./template/iptools/pom.xml"
USAGE="usage: update_rpm_release_in_pom <build num>"
#################
# sanity checks #
#################
# argument given?
[[ $# -eq 1 ]] || \
error "wrong number of parameters\n$USAGE"
# pom file exists?
[[ -e "$POM_FILE" ]] || \
error "pom file $POM_FILE does not exist"
# pom file readable?
[[ -r "$POM_FILE" ]] || \
error "pom file $POM_FILE is not readable"
# pom file writeable?
[[ -w "$POM_FILE" ]] || \
error "pom file $POM_FILE is not writeable"
##################
# set parameters #
##################
BUILD_NUM=$1
###############################
# create temporal output file #
# and ensure its removal #
###############################
# cleanup function
cleanup(){
[[ -e "$TMP_FILE" ]] && rm -- "$TMP_FILE"
}
# ensure cleanup on exit
trap 'cleanup' EXIT
# create temporal output file or exit with error
TMP_FILE=`mktemp` || \
error "could not create temporal output file"
#############################
# process pom file with awk #
# and save modified version #
# in temporal output file #
#############################
awk \
-F "rpm.release>" \
-v OFS="rpm.release>" \
-v BUILD_NUM="$BUILD_NUM" \
'
/<properties>/{
properties=1
}
/<\/properties>/{
properties=0
}
properties&&$1~/<$/&&$2~/<\/$/{
$2=BUILD_NUM"</"
}
1
' "$POM_FILE" > "$TMP_FILE" || \
error "processing pom file $POM_FILE with awk failed"
#########################
# move modified version #
# back to original path #
#########################
mv -- "$TMP_FILE" "$POM_FILE" || \
error "could not mv temporal output file $TMP_FILE to pom file $POM_FILE"
}
# Call above function
update_rpm_release_in_pom 11
然而,这并不像上述解决方案那样稳定。
例如,在我的机器上,这会从pom文件中删除前导空格。
我不知道这是由于报价问题还是您需要调整read
或echo
的参数。
因为我永远不会使用这样的解决方案,所以我不会对此进行进一步调查,但如果您坚持使用
bash
-唯一的解决方案,这可能会对您有所帮助。由于问题被标记,我想awk
将是一个有效的替代方案
在这种情况下,您可以在awk
中处理pom文件,将结果保存在tmpfile中,并用修改后的版本覆盖原始文件:
#!/bin/sh
# error function
error(){
echo -e >&2 "error: $@"
exit 1
}
update_rpm_release_in_pom()
{
#################
# set constants #
#################
POM_FILE="./template/iptools/pom.xml"
USAGE="usage: update_rpm_release_in_pom <build num>"
#################
# sanity checks #
#################
# argument given?
[[ $# -eq 1 ]] || \
error "wrong number of parameters\n$USAGE"
# pom file exists?
[[ -e "$POM_FILE" ]] || \
error "pom file $POM_FILE does not exist"
# pom file readable?
[[ -r "$POM_FILE" ]] || \
error "pom file $POM_FILE is not readable"
# pom file writeable?
[[ -w "$POM_FILE" ]] || \
error "pom file $POM_FILE is not writeable"
##################
# set parameters #
##################
BUILD_NUM=$1
###############################
# create temporal output file #
# and ensure its removal #
###############################
# cleanup function
cleanup(){
[[ -e "$TMP_FILE" ]] && rm -- "$TMP_FILE"
}
# ensure cleanup on exit
trap 'cleanup' EXIT
# create temporal output file or exit with error
TMP_FILE=`mktemp` || \
error "could not create temporal output file"
#############################
# process pom file with awk #
# and save modified version #
# in temporal output file #
#############################
awk \
-F "rpm.release>" \
-v OFS="rpm.release>" \
-v BUILD_NUM="$BUILD_NUM" \
'
/<properties>/{
properties=1
}
/<\/properties>/{
properties=0
}
properties&&$1~/<$/&&$2~/<\/$/{
$2=BUILD_NUM"</"
}
1
' "$POM_FILE" > "$TMP_FILE" || \
error "processing pom file $POM_FILE with awk failed"
#########################
# move modified version #
# back to original path #
#########################
mv -- "$TMP_FILE" "$POM_FILE" || \
error "could not mv temporal output file $TMP_FILE to pom file $POM_FILE"
}
# Call above function
update_rpm_release_in_pom 11
然而,这并不像上述解决方案那样稳定。
例如,在我的机器上,这会从pom文件中删除前导空格。
我不知道这是由于报价问题还是您需要调整read
或echo
的参数。
因为我永远不会使用这样的解决方案,所以我不会对此进行进一步的研究,但如果您坚持使用
bash
-唯一的解决方案,这可能会对您有所帮助。我想,按照关于regex和XML的常见警告,您可以使用regex来实现这一点。很容易。谢谢,我知道这些警告,但我相信我的情况很简单,我可以接受它们。我不是正则表达式专家。您需要增加版本号还是只将其设置为硬编码值?我需要将其设置为存储在局部变量$BUILD_NUM中的传入值。perl-pi-e's/10/11/g'
,而不是bash,但应该这样做。我想,按照关于正则表达式和XML的常见警告,您可以使用正则表达式来实现这一点。很容易。谢谢,我知道这些警告,但我相信我的情况很简单,我可以接受它们。我不是正则表达式专家。您需要增加版本号还是只将其设置为硬编码值?我需要将其设置为存储在局部变量$BUILD_NUM中的传入值。perl-pi-e's/10/11/g'
,而不是bash,但应该这样做。那么这如何适合我的函数呢?这是否会更新pom.xml文件内容?/test.sh:未找到第7行:xmlstarlet:命令。安装模块不是一个选项。这就是我为什么要香草bash的原因。那么它如何适合我的功能呢?这是否会更新pom.xml文件内容?/test.sh:未找到第7行:xmlstarlet:命令。安装模块不是一个选项。这就是为什么我要香草大餐。我会试试这个,谢谢!我的sed版本支持“-i”选项。yesI使用了第一个解决方案,在我修改了适用于我的mktemp调用(在编辑代码中)后,它工作得非常好。谢谢我更新了mktemp
调用,在未指定DIR值的情况下,不使用--tmpdir
选项。我使用GNUmktemp
(coreutils
8.20),这是查找$TMPDIR
环境变量。如果未设置,则使用/tmp
。我猜这是不标准的,对你来说是失败的。代码是否像现在这样为您工作,还是您仍然需要进行调整?我希望我的答案尽可能方便携带。我会试试这个,谢谢!我的sed版本支持“-i”选项。yesI使用了第一个解决方案,在我修改了适用于我的mktemp调用(在编辑代码中)后,它工作得非常好。谢谢我更新了mktemp
调用,在未指定DIR值的情况下,不使用--tmpdir
选项。我使用GNUmktemp
(coreutils
8.20),这是查找$TMPDIR
环境变量。如果未设置,则使用/tmp
。我猜这是不标准的,对你来说是失败的。代码是否像现在这样为您工作,还是您仍然需要进行调整?我希望我的答案尽可能便于携带。