次のコードを実行していくつかの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)}
今私が望むのは、ファイルが次のように見えるように出力を実行し、最後の列に追加することです。
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
これを一度に実行してから、出力をテキストファイルにパイプできますか?
ありがとうございます!
アップデート1
... 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
アップデート2:
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)
答え1
機能を使用してIP /ポートの組み合わせを分割し、後でコマンドで使用できるsplit()
ようにIPをインポートできます。dig()
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
、?
三項演算子を使用して型の値を更新する方法を追加しました。失敗した場合は、'notResolved'
上記の文字列などの独自の文字列を追加して結果を印刷できます。
getline()
発信の使用はawk
呼び出しの使用とは異なりますsystem()
。このタイプはシェルで実行されているcmd | getline var
かのようにパイプを使用し、各呼び出しはコマンドから1行の出力を読み取ります。ただし、このコマンドは内部で実行されたコマンドの出力を取得する方法を提供しません。内部で実行されるコマンドから返された終了コードにのみアクセスできます。cmd
getline var
system()
PS回答セクションに役立つコメントが採択されました。ムル。
答え2
次のことができます。
ステップ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
答え3
awk
完全に避けることもできます。少し遅いですが(同じ呼び出し数を使用してもdig
)読み取りは簡単になります。
while read -r ip count
do
printf "%s %s %s\n" "$ip" "$count" "$(dig +short -x "$ip" | xargs)"
done < ipaddresses.txt