web-dev-qa-db-ja.com

awkの出力を使用してコマンドを実行する

私はシェルスクリプトを初めて使用するので、この一見単純なタスクを理解できないようです。約250行のテキストファイル(ciphers.txt)があり、各行の最初の列をコマンドの引数として使用したいと思います。どんな助けも大歓迎です!

コマンドは次のとおりです。

openssl s_client -connect Host:port -cipher argument

一度に1つずつ実行するとうまくいきますが、同じコマンドを250回以上実行したくありません。これが私のスクリプトです。

awk '{command = "openssl s_client -connect localhost:4433 -cipher > results.txt"
print $0 | command}' ciphers.txt

エラーが発生し続けるので、どこかに構文エラーがあると確信しています。 awkの出力は-cipherの後に追加されますか?

20
nLee

Awk内からsystemを使用します。

awk '{ system("openssl s_client -connect Host:port -cipher " $1) }' ciphers.txt
66
David

コマンドにはかなりの間違いがあります。最初の列を使用したい場合。これはawkでは$ 1と呼ばれ、$ 0ではありません(これが行全体になります)。次に、コマンドの定義の最後にセミコロンを忘れました。

実際にコマンドを実行するには、system()またはパイプを使用できます(後者は、コマンドがstdinから読み取ることができる場合にのみ意味がありますが、あなたのケースではopensslはそうではありません)。最も簡単なのは次のようなものです

awk '{cmd="openssl s_client -connect Host:port -cipher" $1; system(cmd)}' results.txt

これは終了ステータスのみを返すことに注意してください。 stdoutをキャプチャする必要がある場合は、getlineを介してコマンドをパイプする必要があります。

アンドレアス

PS:あなたが得た実際のエラーを投稿すると、助けになるだろう。

11
Andreas

xargsコマンドは、そのユースケース専用です。

awk '{print $0}' <ciphers.txt | xargs -I{} openssl s_client -connect Host:port -cipher {} >>results.txt

このバージョンは、awk$0を解析するためにすでに使用されていたため、この例では少し長くなっています。ただし、xargsは、使用するもののリストが既にあり、サブシェルを実行できるものを実行していない場合に便利です。たとえば、以下のawkを使用してmvを実行できますが、xargsははるかに簡単です。

ls -1 *.txt | xargs -I{} mv "{}" "{}.$(date '+%y%m%d')"

上記のコマンドは、現在のディレクトリ内の各テキストファイルの名前を日付スタンプ付きバックアップに変更します。 awkの同等の機能では、dateコマンドの結果から変数を作成し、それをawkに渡してから、コマンドを作成して実行する必要があります。

xargsコマンドは、複数のパラメーターを1行に蓄積することもできます。これは、入力に複数の列がある場合、または入力ファイルで単一のレコードが繰り返しグループに分割される場合に役立ちます。

それを使用するすべての方法の詳細については、UNIX Mantraで "xargs" All-IN-Oneチュートリアルガイド をご覧ください。

9
T.Rob