在XMLStarlet中处理长编辑列表

在XMLStarlet中处理长编辑列表,xml,bash,xmlstarlet,Xml,Bash,Xmlstarlet,当前Linux发行版中的XMLStarlet版本对每个XMLStarlet ed调用的操作限制为128次,所有版本都受到操作系统最大命令行长度的限制。如何解决这个问题?以下内容将长xmlstarlet编辑列表分解为一系列较短的操作: xmlstarlet_max_commands=100 # max per instance; see http://sourceforge.net/tracker/?func=detail&aid=3488240&group_id=66612&am

当前Linux发行版中的XMLStarlet版本对每个
XMLStarlet ed
调用的操作限制为128次,所有版本都受到操作系统最大命令行长度的限制。如何解决这个问题?

以下内容将长xmlstarlet编辑列表分解为一系列较短的操作:

xmlstarlet_max_commands=100 # max per instance; see http://sourceforge.net/tracker/?func=detail&aid=3488240&group_id=66612&atid=515106
shopt -s extglob # enable +([0-9]) as an equivalent to the regex ^[[:digit:]]+

xmlstarlet_ed() {
  declare -a global_parameters
  declare -a parameters
  declare -i num_commands
  declare -i cmd_len

  global_parameters=( )
  parameters=( )
  num_commands=0

  global_parameters_remaining=$1; shift

  while (( global_parameters_remaining )); do
    global_parameters+=( "$1" ); shift
    (( global_parameters_remaining-- ))
  done

  while (( "$#" )) ; do
    cmd_len=$1; shift
    if ! [[ $cmd_len = +([0-9]) ]] ; then
      echo "ERROR: xmlstarlet_ed commands must be prefixed by run length"
      return 1
    fi

    if (( num_commands < xmlstarlet_max_commands )) ; then
      parameters+=( "${@:1:$cmd_len}" )
      num_commands+=1
      shift $cmd_len
    else
      xmlstarlet ed "${#global_parameters[@]}" "${global_parameters[@]}" "${parameters[@]}" \
        | xmlstarlet_ed "${#global_parameters[@]}" "${global_parameters[@]}" "$cmd_len" "$@"
      return 0
    fi
  done

  if (( ${#parameters[@]} > 0 )) ; then
    xmlstarlet ed "${global_parameters[@]}" "${parameters[@]}"
  else
    cat
  fi
}
xmlstarlet_max_commands=100#max/实例;看见http://sourceforge.net/tracker/?func=detail&aid=3488240&group_id=66612&atid=515106
shopt-s extglob#enable+([0-9])作为regex^[:digit:]的等价物+
xmlstarlet_ed(){
declare-a全局参数
声明-a参数
declare-i num_命令
声明-i cmd_len
全局_参数=()
参数=()
num_命令=0
全局参数剩余=1美元;移位
虽然((全局参数)仍然存在),但是
全局_参数+=(“$1”);移位
((全局参数剩余--))
完成
while(“$#”);do
cmd_len=$1;班次
如果![$cmd_len=+([0-9])];那么
echo“错误:xmlstarlet_ed命令必须以运行长度作为前缀”
返回1
fi
如果((num_命令0),则
xmlstarlet ed“${global_parameters[@]}”“${parameters[@]}”
其他的
猫
fi
}
可以这样调用它:

# first list passed is global parameters; first the count, then the values
# pass only a 0 if no global parameters are desired
global_parameters=( 2 -N "xhtml=http://www.w3.org/1999/xhtml" )

# build up the parameter list as length/command pairs; the lengths are used
# to determine the potential split points between subprocesses
parameters=( )
while read; do
  parameters+=( 8 -s /xhtml:html/xhtml:body -t elem -n line -v "$REPLY" )
done

# ...and actually invoke:
xmlstarlet_ed "${global_parameters[@]}" "${parameters[@]}" \
 <<<"<html xmlns='http://www.w3.org/1999/xhtml'><body/></html>"
#传递的第一个列表是全局参数;首先是计数,然后是值
#如果不需要全局参数,则仅传递0
全局_参数=(2-N“xhtml=http://www.w3.org/1999/xhtml" )
#将参数列表建立为长度/命令对;使用长度
#确定子流程之间的潜在拆分点的步骤
参数=()
边读边读;做
参数+=(8-s/xhtml:html/xhtml:body-t元素-n行-v“$REPLY”)
完成
#…并实际调用:
xmlstarlet_ed“${global_parameters[@]}”${parameters[@]}”\

在实践中,这对你来说是个问题吗?@npostavs是的,是的。请参阅我对的回答,以获取一个示例,该示例用于处理多个输入行。我在商业、生产代码中也提到了这个问题(尽管我所想到的具体示例后来被重写,以便在XQuery中而不是在bash+xmlstarlet中进行相关处理)。+1在一读时没有注意到
xmlstarlet_ed
xmlstarlet ed
之间的区别。我觉得一个简短的通知说
xmlstarlet\u ed
是一个递归函数会在某种程度上提高可读性。