awk入力による2つのSSH出力

awk入力による2つのSSH出力

試している2つのリモートサーバーsshといくつかのファイルがあります。 sshの出力をコマンドcatに供給したいと思います。awk

これは私が持っているものです。


ssh username@host1 “cat /tmp/test/*” ssh username@host2 “cat /tmp/test/*” | awk ‘ command ‘

しかし、これはうまくいきません。host2ディレクトリが空の場合、出力はhost12回繰り返されます。

私がここで何を間違っているのか?

答え1

これらに注意してくださいカール引用符および)一部のWindowsテキストエディタでは、真の引用符('または")を使用します。変数の拡張など、sを'使用する理由がない限り、sを使用する必要があります。"https://mywiki.wooledge.org/Quotes

awkパイプが必要な場合は、次のことを行う必要があります。

{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } | awk ' command '

ただし、後でこれらの区別が必要な場合に備えて、awkが入力がどのコマンドから来たのかを区別できるようにすることを検討してください。

awk ' command ' <(ssh username@host1 'cat /tmp/test/*') <(ssh username@host2 'cat /tmp/test/*')

違いは次のとおりです。

$ seq 3 > file1
$ seq 2 > file2

無効な出力(FILENAME常に含まれてい-ARGV[1..2]空であるため):

$ { cat file1; cat file2; } | awk '
    FILENAME == ARGV[1] { host="host1" }
    FILENAME == ARGV[2] { host="host2" }
    { print host, $0 }
'
 1
 2
 3
 1
 2

無効な出力(同じ一時ファイル記述子が含まれているがFILENAME空であるため):ARGV[1]ARGV[2]

$ awk '
    FILENAME == ARGV[1] { host="host1" }
    FILENAME == ARGV[2] { host="host2" }
    { print host, $0 }
' <(cat file1; cat file2)
host1 1
host1 2
host1 3
host1 1
host1 2

正しい出力:

$ awk '
    FILENAME == ARGV[1] { host="host1" }
    FILENAME == ARGV[2] { host="host2" }
    { print host, $0 }
' <(cat file1) <(cat file2)
host1 1
host1 2
host1 3
host2 1
host2 2

この入力を提供する方法から正しい出力を取得する他の可能な方法は次のとおりです。

$ awk '{print host, $0}' host='host1' <(cat file1) host='host2' <(cat file2)
host1 1
host1 2
host1 3
host2 1
host2 2

答え2

コマンドをグループ化する必要があります。最も簡単な方法は、サブシェルを作成せずに中括弧を使用してグループ化することです。

{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } | 
   awk ' command '

かっこを使用することもできますが、これは不要なサブシェルを生成するため、少しエレガントではありません。ただし、最終結果は同じであり、この場合実際には違いはありません。また、;次のようにエンディングを追加する必要はありません{ }

( ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*' ) | 
   awk ' command '

重複した出力が表示されるのは、両方のコマンドがcat同じホストで実行されるためです。localhost両方のコマンドでホストとして使用され、実行後に出力を確認してくださいset -x

$ ls /tmp/test
file1

$ ssh localhost "cat /tmp/test/*" ssh localhost "cat /tmp/test/*"
+ ssh localhost 'cat /tmp/test/*' ssh localhost 'cat /tmp/test/*'
/tmp/test/file1
/tmp/test/file1
cat: ssh: Is a directory
cat: localhost: No such file or directory
cat: cat: No such file or directory

上記のように、これは "ssh localhost cat arg1 arg2 arg3 arg4"と解釈されるため、on(あなたの場合)を実行し、引数として、(あなたの場合catlocalhost、そしてhost1再度提供されます。したがって、Host1の内容は2回テッドされます。/tmp/test/*sshlocalhosthost2cat/tmp/test/*/tmp/testcat

答え3

ssh1つの可能なアプローチは、サブシェルでコマンドを実行して結果をパイプすることですawk

(ssh username@host1 "cat /tmp/test/*"; ssh username@host2 "cat /tmp/test/*" ) | awk ‘ command ‘

関連情報