次の形式の出力ファイル( "inventory.list")に問題があります。
hostname1.env1.domain | abc | environment1
hostname2.env1.domain | abc | environment1
hostname3.env2.domain | abc | environment2
hostname4.env2.domain | abc | environment2
hostname5.env1.domain | def | environment1
hostname6.env2.domain | def | environment2
(6 rows)
異なる形式で別のファイルに書き込みます。
[abc.environment1]
hostname1.env1.domain
hostname2.env1.domain
[abc.environment2]
hostname3.env2.domain
hostname4.env2.domain
[def.environment1]
hostname5.env1.domain
[def.environment2]
hostname6.env2.domain
abc
役割はサーバーに割り当てられ、def
各役割は複数のサーバーを持つことができるだけでなく、名前は同じですが、環境が異なる役割を持つことができます。各ホスト名を一意の[role.environment]グループに分割し、さらに行数であるファイルの最後の行を完全に削除する必要がありました(ファイルはSQLクエリの出力です)。
ファイルを読み込み、パイプとスペースを削除し、役割/環境グループを割り当て/出力できます。問題ありません。
#! /bin/bash
while IFS='| ' read -r certname role env; do
printf '%s\n' "[""$role"".""$env""]"
done < "/tmp/inventory.list"
...役割/環境グループ名をきれいに提供します。
[abc.environment1]
[abc.environment2]
[def.environment1]
[def.environment2]
ただし、各グループ名の下の各役割/環境グループに関連付けられているホスト名を印刷する方法はわかりません。私の役割と環境フィールド(2番目と3番目のフィールド)を独自の配列に追加割り当ててから、それを参照して各一意のグループに関連付けられているホスト名を取得する必要がありますが、今はどうすればいいのかわかりません。 。誰でもアドバイスできますか?
答え1
テキストユーティリティを使用してテキストを処理します。シェルループを使用してテキストを処理する代わりに(ここではIFS=' |'
あなたの場合はうまくいきます)。良い:
awk -F ' *[|] *' '
NF == 3 {host[$2"."$3] = host[$2"."$3] $1 "\n"}
END{for (i in host) print "[" i "]\n" host[i]}' < file
出品順序は保証されません。 GNUを使用してキーベースのソートをawk
追加します。BEGIN{PROCINFO["sorted_in"] = "@ind_str_asc"}
使用しているRDBMSに応じて正しい形式で表示することもできます(例:GROUP_CONCAT
存在するmysql
またはstring_agg
ポストグレスから)。
まず、RDBMSクエリユーティリティに出力を後処理に適した形式で指定するように要求することもできます(たとえば、ヘッダー、フッターの削除、タブ区切り値を使用)。
答え2
連想配列を使用して、各役割と環境の証明書名を保存します。
#! /bin/bash
unset -v envs
declare -A envs
while IFS='| ' read -r certname role env; do
envs["$role.$env"]+="$certname"$'\n'
done < /tmp/inventory.list
for e in "${!envs[@]}" ; do
printf '%s\n' "[$e]" "${envs[$e]}"
done
これらの部分をソートするには、キーを印刷してソートしてから、再度読み込み、関連値を出力します。
for e in "${!envs[@]}" ; do
printf '%s\n' "$e"
done | sort | while read -r e ; do
printf '%s\n' "[$e]" "${envs[$e]}"
done
答え3
パールマジック:
$ perl -lne '@F=split(/\s*\|\s*/); push @{$k{"$F[1].$F[2]"}},$F[0];
END{foreach (keys(%k)){print "[$_]"; print join "\n",@{$k{$_}}} }' file
[abc.environment1]
hostname1.env1.domain
hostname2.env1.domain
[def.environment1]
hostname5.env1.domain
[abc.environment2]
hostname3.env2.domain
hostname4.env2.domain
[def.environment2]
hostname6.env2.domain
答え4
awkを使用する1つの方法:
$ sed 's/ //g' file | awk -F"|" '{x="["$2"."$3"]";}!(x in a){print x;a[x];}{print $1}'