シェル変数で、コマンドの後のパラメータ(角かっこ)をキャプチャします。

シェル変数で、コマンドの後のパラメータ(角かっこ)をキャプチャします。

他の多くのコンテンツを含むファイルがあるとしましょう。

\コマンド{arg1、arg2、arg3}

(パラメータはパスであり、、、/文字.、数字で表されます)

ただし、ユーザーは以下を使用することもできます。

\command{arg1,
arg2 ,
arg3
}

つまり、余分なスペースがある複数行です。

n個の変数にn個のパラメータが含まれるように、シェルスクリプトに含まれる一般的なパターンを見つけたいと思います。どうやって進めますか?


文を書くことに成功した

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

しかし、これは出力のみ可能arg1であり、それを変数に保存する方法さえわかりません。

関連:

しかし、これらすべての材料を組み合わせて私が望むものを得ることはできません。

答え1

n個の変数にn個のパラメータが含まれるように、シェルスクリプトに含まれる一般的なパターンを見つけたいと思います。

以下は、arglist各パラメータを含むシェル配列を作成します。

$ 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")'

以下は、1行にパラメータがある別の例です。

$ 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コマンドは少し微妙です。一度に1つずつ見てみましょう。

  • -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

関連情報