xml - 在 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&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
}

可以这样调用:

# 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>"

关于xml - 在 XMLStarlet 中处理长编辑列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9898939/

相关文章:

c# - 如何使用 C# 更新 XML 中的节点值

linux - 在登录时执行 bash 并添加别名

linux - 获取不存在文件的数量

bash - 通过重定向运行 awk

xml - 如何使用 xmlstarlet 插入现有的 xml 行

xml - 如何使用 xmlstarlet 或类似工具附加或前置到 xml 文件中的属性?

java - 我想以编程方式向我的 android 按钮添加多个字符串(不是通过 XML)

c# - XNA XML 序列化问题

GO 中的 XML 解码

linux - 在 concat() 中的 csv 中添加换行符