コマンドの列を新しいコマンドに分割

コマンドの列を新しいコマンドに分割

自動的にデバイスを生成するスクリプトを作成しようとしています。長い道のりが来たけど詰まった

ソースファイルは次のとおりです。

dev1 size 1024
dev2 size 1024
dev3 size 1024
dev4 size 512
dev5 size 512

スクリプトでは、ソースファイルは$ INVFILE変数です。その後、コマンドを発行します。

cat $INVFILE | awk '{print $3}' | sort | uniq -c

次の出力を提供します。

   3 1024
   2 512

次のコマンドでは、この出力を使用してさまざまなサイズと数を使用したいと思います(この例では最初の行のみを使用しますが、スクリプトでは関数に「for i in」を使用したいと思います)。

create dev count=3 size=1024MB

スクリプトでこれをどのように実行できますか? 「for i in」機能を置き換えるより簡単な方法はありますか?

答え1

awkは全部できます。

努力する

awk '{ d[$3]++ ; } 
     END { for ( c in d ) 
        printf "create dev count=%d size=%dMB\n",d[c],c ;}' $INVFILE

動作する場合:

awk '{ d[$3]++ ; } 
   END { for ( c in d ) 
         printf "create dev count=%d size=%dMB\n",d[c],c ;}' $INVFILE |
bash

答え2

awk '{print $3}' $INVFILE | sort | uniq -c | \
while read a b ; do \
    create dev count=$a size=${b}MB ; \
done

~のためループサイクルごとに1つのリスト項目のみが使用されます。x_1 x_2 x_3を読むとき...どんなに使ってもx_nSはい。 (ただし、入力ファイルの1行のエントリ数を超えることはできません。)

ノート、もし2つ以上の列を持つ入力の場合は、上記の「read ab」を「read ab c」に変更します。$cループでは使用されませんが、読み取りが残りの行を割り当てないようにします。$b


最初のパイプラインは次のように交換できます。データ混合$a&$bループで交換:

datamash -W -s -g3 count 3 < $INVFILE | \
while read a b ; do \
    create dev count=$b size=${a}MB ; \
done

答え3

まず、 'uniq' -コマンドにはn個の列を無視する '-f N'オプションがあります。

その後、「read」を使用して入力のフィールドを変数に入れることができます。

したがって、要約すると、次のコマンドは入力ファイルのすべての行から必要な情報を選択します。

cat input.txt | uniq -f2 -c | while read a b c d; do echo "command $a $d" ;done

「echo...」を希望のコマンドに置き換えてください。

関連情報