1

我用谷歌搜索了这个,但找不到具体的答案。

我有一个带有以下标签的 pom.xml 文件

<properties>
    <rpm.release>10</rpm.release>
</properties>

然后,我必须遵循脚本来查找标签之间的标签,这很有效。

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

我应该在“#How do I update value???”中输入什么?所以当我运行脚本时, pom.xml 现在有了

<properties>
    <rpm.release>11</rpm.release>
</properties>

谢谢。

4

2 回答 2

2

由于问题被标记为,我想awk这将是一个有效的选择。

在这种情况下,您可以在 中处理 pom 文件awk,将结果保存在 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

请注意,这应该适用于所有版本,awk因为那里没有 GNUisms。

可能有一种方法可以通过使用inplace ( ) 选项来执行此操作sed并绕过 tmpfile 内容,但是 a) 我不确定如何以安全的方式执行此操作b) 我什至不知道您是否运行支持该选项的版本。sed-isedsed-i

如果您需要进一步的帮助、调整和/或解释,请随时添加评论。

附录:

如果您真的需要在没有任何脚本语言的情况下执行此操作,我修改了您的代码并将我的awk代码替换为:

#!/bin/bash

# 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 bash #
  # and save modified version  #
  # in temporal output file    #
  ##############################

  BEGIN_PROPERTIES="n"
  while read LINE
  do
    case $BEGIN_PROPERTIES in
      n) # <property> tag not found yet
        [[ "$LINE" == *\<properties\>* ]] && BEGIN_PROPERTIES="y"
        echo "$LINE"
        continue
      ;;
      y) # <property> tag found
        [[ "$LINE" == *\</properties\>* ]] && BEGIN_PROPERTIES="n"
        if [[ "$LINE" == *rpm.release* ]]; then
          # Update value
          echo "${LINE/<rpm\.release>*<\/rpm\.release>/<rpm.release>$BUILD_NUM<\\rpm.release>}"
          continue
        fi
        echo "$LINE"
      ;;
    esac
  done < "$POM_FILE" > "$TMP_FILE" || \
    error "processing pom file $POM_FILE with bash 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 文件中删除前导空格。我不知道这是由于某些引用问题还是您需要调整reador的参数echo。由于我永远不会使用这样的灵魂,因此我不会对此进行进一步调查,但如果您坚持使用bash-only 解决方案,这可能会对您有所帮助。

于 2013-09-26T11:59:44.643 回答
-1

你可以使用

[[ $LINE =~ ^([^>]+>)([0-9]+)(.*) ]] && printf -v LINE "%s%d%s" \
    "${BASH_REMATCH[1]}" \
    $(( ${BASH_REMATCH[2]} + 1 )) \
    "${BASH_REMATCH[3]}"

BASH_REMATCH是操作员设置的数组,=~用于存储捕获括号内的值。


它只是更新该行。我会使用我最喜欢的命令行 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
}
于 2013-09-20T15:42:32.440 回答