在 shell 变量中捕获命令后的参数(括号之间)

在 shell 变量中捕获命令后的参数(括号之间)

假设我有一个文件,其中包含许多其他内容,

\命令{arg1,arg2,arg3}

(参数为路径,用/, ., 字符和数字表示)

但用户也可以用

\command{arg1,
arg2 ,
arg3
}

也就是说,多行且有多余的空格。

我想找到一个包含在 shell 脚本中的常规模式,以便 n 个变量将包含 n 个参数。如何进行 ?


我设法写了

echo "\command{arg1,
    arg2 ,
    arg3
    }" | sed -n -e 's/\\command//p' | sed 's/,/\n/' | sed 's/{\|}//'

但这仅输出arg1,我什至不确定如何将其存储在变量中。

有关的:

但我无法将所有这些成分结合起来以获得我想要的东西。

答案1

我想找到一个包含在 shell 脚本中的常规模式,以便 n 个变量将包含 n 个参数

以下创建一个arglist包含每个参数的 shell 数组:

$ readarray -t arglist < <(echo "\command{arg1,
    arg2 ,
    arg3
    }" | sed -n '/\\command/{ :a;/}/!{N;b a}; s/\\command{//; s/[ \n}]//g; s/,/\n/g; p}')

通过使用该declare语句,我们可以看到它有效:

$ declare -p arglist
declare -a arglist='([0]="arg1" [1]="arg2" [2]="arg3")'

这是另一个示例,参数位于一行:

$ readarray -t arglist < <(echo "\command{arg1, arg2, arg3, arg4}"  | sed -n '/\\command/{ :a;/}/!{N;b a}; s/\\command{//; s/[ \n}]//g; s/,/\n/g; p}')

再说一遍,它有效:

$ declare -p arglist
declare -a arglist='([0]="arg1" [1]="arg2" [2]="arg3" [3]="arg4")'

请注意, 中的空格< <(至关重要。我们正在重定向来自进程替换的输入。没有空间,bash将尝试完全不同的东西。

怎么运行的

这个sed命令有点微妙。让我们一次看一下:

  • -n

    除非明确要求,否则不要打印行。

  • /\\command/{...}

    如果我们找到包含 的行\command,则执行大括号中的命令,如下所示:

  • :a;/}/!{N;b a}

    这会将行读入模式缓冲区,直到我们找到包含 的行}。这样,我们就可以立即输入整个命令。

  • s/\\command{//

    取下\command{绳子。

  • s/[ \n}]//g

    删除所有空格、右大括号和换行符。

  • s/,/\n/g

    用换行符替换逗号。完成此操作后,每个参数都位于单独的行上,这正是我们readarray想要的。

  • p

    打印。

答案2

perl

perl -l -0777 -ne '
  $n = 0;
  for (/\\command\{\s*(.*?)\s*\}/sg) {
    $n++;
    $i = 0;
    for $arg (split /\s*,\s*/, $_) {
      $arg =~ s/'\''/$&\\$&$&/g;
      print "arg${n}[$i]='\''$arg'\''";
      $i++;
    }
  }
  print "n=$n"' the-file

会输出类似:

arg1[0]='arg1'
arg1[1]='arg2'
arg1[2]='arg3'
n=1

你可以这样评估:

eval "$(perl ...)"

为每个s创建$arg1, ... 数组。$arg2\command

相关内容