sedまたはawkを再度呼び出すことなく、どのように文字列からドット文字を削除できますか?

sedまたはawkを再度呼び出すことなく、どのように文字列からドット文字を削除できますか?

次のテキストを含むファイルがあります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.txt1000個のホストが含まれているので、スクリプトが高速で効率的であることを願っています。

答え1

Commands sedawkコマンド、および末尾のピリオドの削除をすべて単一の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ステートメントの後にあるため、awk1つのプロセスのみが呼び出されます。ここで効率は重要ではないかもしれませんが、各ループで新しい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番目のステートメントはf0(false)にリセットされます。

    つまり、fここでは論理条件が重要な役割を果たします。f0以外の場合(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

関連情報