web-dev-qa-db-ja.com

awkでsystem()関数を使用して最初の列でコマンドを実行する

私はいくつかのIPアドレスを抽出し、それらの一意をカウントするために実行している次のコードを持っています。例えば

_./my_program | awk '/^10./{a[$1 FS $2]++ } END { for(i in a) print i,a[i]}' > some_file
_

_some_file_に含まれる出力は次のとおりです。

_10.12.33.14 34
10.12.33.11 12
10.12.33.16 5
_

次に、{system("Dig +short -x " i)}を実行し、最後の列にoutを追加して、ファイルが次のようになるようにします

_10.12.33.14 34  server1.rdns.domain.tld
10.12.33.11 12  server2.rdns.domain.tld
10.12.33.16 5   server3.rdns.domain.tld
_

これを一度に実行して、出力をテキストファイルにパイプ処理できますか?

ありがとう!

pdate1

_... END { for(i in a) cmd=sprintf("Dig +short -x \"%s\"", $i); cmd | getline type; close(cmd);  printf("%s %s %s\n",i,a[i],type);
_

これは出力で終わるものです(stderr)

_Dig: '.in-addr.arpa.' is not a legal name (unexpected end of input)
_

これは私がファイルで見るものです

_10.12.33.14 34
_

pdate2:

_    END { for(i in a) split(i,ip," ")
    cmd=sprintf("Dig +short -x \"%s\"", ip[1]); cmd | getline type; close(cmd);
    printf("%s %s %s %s\n",ip[1],ip[2],a[i],type)
_
4
holasz

split()関数を使用してIP /ポートの組み合わせを分割し、後でDig()コマンドで使用するためにIPを取得できます。

_END { 
  for(i in a) {
    split(i, ip)
    cmd=sprintf("Dig +short -x \"%s\"", ip[1])
    (cmd | getline type) > 0 ? "" : type="notResolved"
    printf("%s %s %s\n",i,a[i],type);
    close(cmd)
  }
}
_

Digコマンドのステータスを確認する方法を追加し、_?_三項演算子を使用してtypeの値を更新しました。失敗した場合は、独自の文字列(上記の_'notResolved'_など)を追加して結果を出力できます。

awkgetline()呼び出しを使用することは、system()呼び出しを使用することと同じではないことに注意してください。タイプ_cmd | getline var_は、cmdがシェルから実行されるかのようにパイプを使用して、_getline var_を呼び出すたびにコマンドから1行の出力を読み取ります。 system()コマンドは、内部で実行されたコマンドの出力を取得する方法を提供していません。内部で実行されたコマンドから返された終了コードにのみアクセスできます。

追伸 muru。 の有用なコメントから部分的に採用された回答

6
Inian

次のことができます

ステップ1:

./my_program | awk '/^10./{a[$1]++ } END { for(i in a) print i,a[i]}' | tee some_file | xargs -I{} Dig +short -x {} > some_file2

ステップ2:

paste <(awk '{print $1}' some_file ) <(awk '{print $1}' some_file2 ) > result

削除できますsome_fileおよびsome_file2 ご希望の場合。 rm some_file some_file2

1
Pushpam Kumar

awkの使用をまったく回避することもできます。少し遅くなりますが(Digの呼び出し数は同じですが)、おそらくもっと読みやすくなります。

while read -r ip count
do
    printf "%s %s %s\n" "$ip" "$count" "$(Dig +short -x "$ip" | xargs)"
done < ipaddresses.txt
0
roaima