Linuxのさまざまな場所にヘッダーを追加する必要があるファイルがあります。 「ヘッダー」はファイルなので、最初の行にのみ追加できます。しかし、今では、特に新しいIPアドレスを見つける前に、複数の場所に同じヘッダーを追加したいと思います。実際にヘッダーを持つファイルは必要ありません。すべての出力を取得したら、awkまたはsedを介してテキストを追加するだけです。
ヘッダーは新しいIPアドレスを見つけた直後に挿入する必要があります。
リストは可変です。たとえば、ip 192.168.10.10には3つのエントリがありますが、さらに存在する可能性があります。たとえば、ip 192.168.10.33 には 2 つのエントリがありますが、より多くの場合があります。ポートはデフォルトでソートされます。 IP アドレスはソートされずにグループ化されます。
出力は次のとおりです。
192.168.10.10 1/1/2
192.168.10.10 1/1/3
192.168.10.10 1/1/4
192.168.10.33 1/1/2
192.168.10.33 1/1/6
192.168.10.20 1/1/6
192.168.10.20 1/1/7
192.168.10.20 1/1/10
192.168.10.20 1/1/18
出力が次のようになります。
SWITCH ID PORT
192.168.10.10 1/1/2
192.168.10.10 1/1/3
192.168.10.10 1/1/4
SWITCH ID PORT
192.168.10.33 1/1/2
192.168.10.33 1/1/6
SWITCH ID PORT
192.168.10.20 1/1/6
192.168.10.20 1/1/7
192.168.10.20 1/1/10
192.168.10.20 1/1/18
答え1
これはヘッダーを追加するかなり長いawkスクリプトです。
NR==1 {
print "SWITCH ID PORT"
print $0
prev=$1
next
}
$1!=prev {
print ""
print "SWITCH ID PORT"
print $0
prev=$1
next
}
$1==prev {
print $0
}
ファイルとして保存してください。例えばaddheader.awk
このように電話してください
awk -f addheader.awk inputfile
それとも
commandproducinginput | awk -f addheader.awk
スクリプトの説明
awkの動作原理はおおよそ次のとおりです。
for every line of input
for every rule
if condition is true
execute code block
「ルール」は条件とコードブロックのペアです。
上記のコードのルール例
NR==1 {
print "SWITCH ID PORT"
print $0
prev=$1
next
}
これがNR==1
条件です。中かっこ内の部分は{...}
コードブロックです。
NR
行番号(正確にはレコード番号)を含むawk固有の変数。したがって、NR==1
最初の行だけが正確です。
最初の行では、ヘッダー行を印刷します。次に、実際の行($0
現在の行のawk変数)を印刷します。次に、この行のIPアドレス($1
現在の行の最初のフィールドのawk変数)を覚えておいてください。その後、awkが他の規則を考慮しないように、次の行に直接移動すると言います。ループから外れることをnext
想像できます。break
for every rule
$1!=prev
現在のIPアドレスが前のアドレスと一致しない場合、次のルールの条件はtrueです。この場合、空白行を印刷します。それからタイトルがあります。その後、行自体があります。次に、この新しいIPアドレスを覚えておいてください。次に、次の行に移動します。
最後のルールは「Default Case」です。 IPアドレスが以前と同じ場合は、その行をそのまま印刷します。
next
上記のルールはif else ifチェーンを効果的に形成します。
擬似コードではおおよそ次のようになります。
for every line:
if is first line:
print header then line
else if IP adress is different than previous:
print empty line then header then line
else if IP adress is same to previous:
print line
ボーナス:
次のバリエーションは同じです。
最後のコードブロックを省略します。
NR==1 {
print "SWITCH ID PORT"
print $0
prev=$1
next
}
$1!=prev {
print ""
print "SWITCH ID PORT"
print $0
prev=$1
next
}
$1==prev
コードブロックが欠落している場合、デフォルトの動作はその行をそのまま印刷することです。
または条件を省略し、コードブロックを保持します。
NR==1 {
print "SWITCH ID PORT"
print $0
prev=$1
next
}
$1!=prev {
print ""
print "SWITCH ID PORT"
print $0
prev=$1
next
}
{
print $0
}
条件が欠落している場合、これは暗黙的に真です。これはnext
、上記のルールがif else ifチェーンを効果的に形成するためです。最後のルールは最後のelseに似ているため、条件は必要ありません。
ルールの並べ替え
$1==prev
NR==1 {
print "SWITCH ID PORT"
print $0
prev=$1
}
$1!=prev {
print ""
print "SWITCH ID PORT"
print $0
prev=$1
}
このように省略することはできますが、next
私の好みは読みやすくなります。
共通コードを関数として抽出
func common() {
print "SWITCH ID PORT"
print $0
prev=$1
next
}
NR==1 {
common()
}
$1!=prev {
print ""
common()
}
$1==prev
すべての変数はawkのグローバル変数です。