8

フォームの複数の埋め込みループを特徴とする BASH ファイルを作成しました

for P in {'0.10','0.20', [...] '0.90','1.00'}; do 
   for Q in {'0.10','0.20', [...] ,'0.90','1.00'}; do
    [...] 

これらの変数は、コマンド ライン アプリケーションのパラメーターとしても、BASH で直接ファイル名を作成するためにも使用します。重複を作成したいと思います。たとえば$P_REP=0_10、すべての場合に明示的な switch ステートメントを記述せずにドットをアンダースコアに置き換えたり、ハードコードされた同等のものを作成したりします。私が見つけた(エレガントではない方法)は、

  1. P,Qの内容を一時ファイルにダンプします。
  2. を使用して、ドットをアンダースコアに置き換えますsed 's/./_/ -i
  3. ファイルを再度読み取り、その内容を新しい変数にロードします。

したがって、変数の内容に対して sed のようなコマンドを直接実行できるかどうか疑問に思っていましたか?

4

5 に答える 5

20

bash で直接パターン置換を行うことができます。

P_REP=${P/./_}
Q_REP=${Q/./_}

bash(1) の man ページから:

パラメータ展開

${parameter/pattern/string}

パターン置換。 パス名の 展開と同様に、パターンが展開されてパターンが生成されます。 パラメータが展開され、その値に対するpatternの最長一致がstringに置き換えられます。patternが で始まる場合、 pattern/のすべての一致がstringに置き換えられます。通常、最初の一致のみが置き換えられます。パターンが で始まる場合、パラメータの展開された値の先頭で一致する必要があります。パターンが で始まる場合、パラメータの展開された値の最後で一致する必要があります。文字列の場合#%が null の場合、パターンの一致は削除され、/ に続くパターンは省略される場合があります。パラメータが@または*の場合、置換操作は各位置パラメータに順番に適用され、展開は結果のリストです。@parameter がorで添字付けされた配列変数である場合*、置換操作は配列の各メンバーに順番に適用され、展開は結果のリストになります。

于 2013-10-23T20:30:22.673 に答える
13

John Kugelman の答えはあなたの例では問題ありませんが、変数の内容を実際の sed プログラム (またはその他の任意のコマンド) で処理する必要がある場合は、次のようにすることができます。

P_REP=$(sed 's/\./_/' <<< "$P")
于 2013-10-23T20:36:23.937 に答える
0

使用できるループの場合:

#!/bin/bash
P_REP=$(for P in '0.10' '0.20' '0.90' '1.00'; do echo ${P/./_} ; done)
Q_REP=$(for Q in '0.10' '0.20' '0.90' '1.00'; do echo ${Q/./_} ; done)

echo ${P_REP[@]}
echo ${Q_REP[@]}
于 2013-10-23T20:32:57.353 に答える
0

あなたが言及している正確な問題については、上記のジョンの命題を使用してください。

ただし、bashのパターン置換構文では解決できない同様のことを行う必要がある場合に備えて、sedまたは同様のコマンドでコンテンツを変換するために一時ファイルを実際に作成する必要はありません。まず、変数を STDIN としてプログラムに直接パイプできます。次に、コマンドの出力 (STDOUT、STDERR、またはその両方) を直接シェル変数に入れることができます。

したがって、あなたの例では、次のようになります。

for P in 0.10 0.20 [...] 0.90 1.00 ; do 
   for Q in 0.10 0.20 [...] 0.90 1.00 ; do
        P_REP=$( sed 's/\./_/g' <<< "$P" )
        Q_REP=$( sed 's/\./_/g' <<< "$Q" )
   done
done

また、配列構文 (つまり{ '0.10', '0.20', ...}) はほとんどが Bash に固有であり、Bash フォロワーはほとんどいないことに注意してください。簡単に実行できる場合は、上で説明したように、シェルの for ループに対するより古典的なアプローチを好むかもしれません。その後、コードはすべての posix 準拠シェルで安全に実行されます。

于 2013-10-23T20:39:41.370 に答える