如何在bash中使用逗号分隔的引用子字符串列表解析字符串?

时间:2018-08-06 17:13:58

标签: bash

我想读取无限数量的args,而不是只读取一组3。

获取以下文件:

C1 C2 R1 10 R2 10 R3 10 R4 10 R5 10 R6 10 R7 20

packages

deb "bat" [args: "https://github.com/sharkdp/bat/releases/download/v0.4.1/bat_0.4.1_amd64.deb", "$HOME", "bat_0.4.1_amd64.deb"]

custom function

1 个答案:

答案 0 :(得分:1)

首先:在这是您自己构建的序列化格式中,不要这样做。使用现成的格式和工具要健壮得多:例如,使用JSON,您可以可以使用jqjsawk,Perl / Python中的JSON模块,等等。

但是要回答所问的问题...


在可能重复的项目周围放置一个匹配组,然后从该组中选择较小的项目,直到没有可用的对象为止-像这样:

apt_install_from_file() {
  local line multi_args_str last_arg
  local -a args
  local deb_re='deb[[:space:]]+"([^"]*)"[[:space:]]+\[args:[[:space:]]+(("([^"]*)",[[:space:]]*)*)("([^"]*)")[[:space:]]*\]'
  local multi_args_re='[[:space:]]*"([^"]*)",[[:space:]]*'

  args=( )
  while read -r line; do
    [[ $line =~ $deb_re ]] || continue
    [[ $- = *x* ]] && declare -p BASH_REMATCH >&2 # debug
    multi_args_str=${BASH_REMATCH[2]}
    last_arg=${BASH_REMATCH[6]}
    args=( "${BASH_REMATCH[1]}" )
    while [[ $multi_args_str =~ $multi_args_re ]]; do
      args+=( "${BASH_REMATCH[1]}" )
      multi_args_str=${multi_args_str#"${BASH_REMATCH[0]}"}
    done
    args+=( "$last_arg" )
    printf 'Parsed line %s to array:\n' "$line"
    declare -p args
  done
}

...在给出您的输入行时正确发射:

Parsed line deb "bat" [args: "https://github.com/sharkdp/bat/releases/download/v0.4.1/bat_0.4.1_amd64.deb", "/home/6lEee0", "bat_0.4.1_amd64.deb"] to array:
declare -a args=([0]="bat" [1]="/home/6lEee0" [2]="bat_0.4.1_amd64.deb")

类似地,给定更长的输入行,它可以返回:

Parsed line deb "bat" [args: "https://github.com/sharkdp/bat/releases/download/v0.4.1/bat_0.4.1_amd64.deb", "/home/pShbET", "bat_0.4.1_amd64.deb", "foo", "bar", "baz", "qux"] to array:
declare -a args=([0]="bat" [1]="https://github.com/sharkdp/bat/releases/download/v0.4.1/bat_0.4.1_amd64.deb" [2]="/home/pShbET" [3]="bat_0.4.1_amd64.deb" [4]="foo" [5]="bar" [6]="baz" [7]="\"qux\"")

https://ideone.com/fC37Fq上查看此操作