次のテキストを含むファイルがありますhostlist.txt
。
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
次のような小さなスクリプトがあります。
#!/usr/local/bin/bash
while read host; do
dig +search @ns1.mydomain.com $host ALL \
| sed -n '/;; ANSWER SECTION:/{n;p;}';
done <hostlist.txt \
| gawk '{print $1","$NF}' >fqdn-ip.csv
出力は次のとおりですfqdn-ip.csv
。
host1.mydomain.com.,10.0.0.1
host2.mydomain.com.,10.0.0.2
anotherhost.internal.mydomain.com.,10.0.0.11
www.mydomain.com.,10.0.0.10
login.mydomain.com.,10.0.0.12
somehost.internal.mydomain.com.,10.0.0.13
host3.mydomain.com.,10.0.0.3
.
私の質問は、前にカンマを削除する方法ですいいえsed
もう一度電話してくださいgawk
。既存のsed
手順を実行したり、gawk
ポイントを削除するように呼び出すことはできますか?
hostlist.txt
1000個のホストが含まれているので、スクリプトが高速で効率的であることを願っています。
答え1
Commands sed
、awk
コマンド、および末尾のピリオドの削除をすべて単一のawkコマンドに組み合わせることができます。
while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
または複数行にわたって展開します。
while read -r host
do
dig +search "$host" ALL
done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
awk
ステートメントがdone
ステートメントの後にあるため、awk
1つのプロセスのみが呼び出されます。ここで効率は重要ではないかもしれませんが、各ループで新しいsedまたはawkプロセスを作成するよりも効率的です。
はい
このテストファイルを使用すると、次のようになります。
$ cat hostlist.txt
www.google.com
fd-fp3.wg1.b.yahoo.com
このコマンドは以下を生成します。
$ while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
www.google.com, 216.58.193.196
fd-fp3.wg1.b.yahoo.com, 206.190.36.45
どのように動作しますか?
awk は、一度に 1 レコード(行)ずつ入力を暗黙的に読み込みます。このawkスクリプトは、f
前の行が回答セクションのタイトルかどうかを示す単一の変数を使用します。
f{sub(/.$/,"",$1); print $1", "$NF; f=0}
前の行が回答セクションのタイトルの場合、
f
これはtrueになり、中括弧内のコマンドが実行されます。最初は、最初のフィールドから末尾のピリオドを削除します。 2番目は最初のフィールドを印刷し、最後の,
フィールドを印刷します。 3番目のステートメントはf
0(false)にリセットされます。つまり、
f
ここでは論理条件が重要な役割を果たします。f
0以外の場合(awkで「true」を意味する)、中括弧で囲まれたコマンドが実行されます。/ANSWER SECTION/{f=1}
現在の行に文字列が含まれている場合、
ANSWER SECTION
この変数は(true)f
に設定されます。1
ここでは
/ANSWER SECTION/
論理条件として機能します。現在の値が正規表現と一致する場合、その値はtrueですANSWER SECTION
。その場合は、中かっこで囲まれたコマンドを実行します。
答え2
dig
ホスト名のリストを含むファイルを読み取り、1つずつ処理することができます。dig
回答セクションを除くすべての出力を抑制するように指示することもできます。
これにより、希望の出力が提供されます。
dig -f hostlist.txt +noall +answer +search |
awk '{sub(/\.$/,"",$1); print $1","$5}'
awk
このsub()
関数は、.
最初のフィールドの末尾からリテラルピリオドを削除します。次に、awk
フィールド1と5をカンマで区切って印刷します。
注:hostlist.txt
解析されていない項目は完全に削除されます。 stdoutまたはstderrには表示されません。
(LinuxとFreeBSDでテスト済み)
答え3
呼び出しをgawk
次に変更します。
| gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv