次のように、サーバーとドメイン名を含むファイルがあります。
名前.txt:
ABCDomain ContractABCServer_1
ABCDomain ABC_server1
LinkDomain CoreLinkServer_1
TADDomain TADServer_1
(他のファイルに対してソートと独自の操作を実行した後、上記のファイルを取得しました。)---
上記のファイルから値を抽出し、xyzコマンド(サーバーを再起動するために使用されます)に次の形式の引数として渡す必要があります。
出力:
"ABCDomain(server:ContractABCServer_1,server:ABC_server1)","LinkDomain(server:CoreLinkServer_1)","TADDomain(TADServer_1)"
以下に説明するロジックを使用していますが、各コレクションのドメイン名は一度だけ表示される必要があるため、目的の出力は提供されません。私も同じラインを維持するのが難しいです。
- - - - - - -スタート- - -
DOMAIN=''
IFS=' '
while read line
do
DOMAIN=$(echo "$line" | awk -F " " '{print $1}')
for word in $line
do
if [[ "$word" == "$DOMAIN" ]]; then
Server=$(echo "$line" | awk -F " " '{print $2}' )
echo -n "(server:$ServerName"
fi
done
done < Names.txt
答え1
{
if (dom[$1])
dom[$1]=dom[$1]","$2
else
dom[$1]=$2
}
END {
ORS=",";
for (d in dom)
if (d)
print ("\""d"(server:"dom[d]")""\"")
}
高速で汚れたawkソリューションは次のとおりです。 Something.awkとして保存し、以下を実行します。
awk -f something.awk Names.txt
あなたの質問に答えるためのクイックフィックスコメント:
{ dom[$1]=dom[$1] ? dom[$1]",server:"$2 : "server:"$2 }
END {
for (d in dom)
if (d) {
out && out = out","
out = out"\""d"("dom[d]")""\""
}
print out
}
答え2
カンマで区切られた文字列を直接結合し、awk
最後に組み合わせを印刷できます。
$1 == "ABCDomain" {d = (d == "") ? $2 : d "," $2; next}
$1 == "LinkDomain" {l = (l == "") ? $2 : l "," $2; next}
$1 == "TADDomain" {t = (t == "") ? $2 : t "," $2; next}
END {
printf("\"ABCDomain(server:%s)\",\"LinkDomain(server:%s)\",\"TADDomain(%s)\"\n", d, l, t)
}
前任者。
$ awk '
$1 == "ABCDomain" {d = (d == "") ? $2 : d "," $2; next}
$1 == "LinkDomain" {l = (l == "") ? $2 : l "," $2; next}
$1 == "TADDomain" {t = (t == "") ? $2 : t "," $2; next}
END {
printf("\"ABCDomain(server:%s)\",\"LinkDomain(server:%s)\",\"TADDomain(%s)\"\n", d, l, t)
}' Names.txt
"ABCDomain(server:ContractABCServer_1,ABC_server1)","LinkDomain(server:CoreLinkServer_1)","TADDomain(TADServer_1)"
答え3
このコードを使用できます。/tmp
そのフォルダにディレクトリが作成されたdomains
後に削除されるため、実行する前にコードをお読みください。
DOMAIN=''
IFS=' '
declare -A domain
mkdir /tmp/domains
while read line
do
DOMAIN=$(echo $line | awk '{print $1}')
SERVER=$(echo $line | awk '{print $2}' )
echo "$SERVER," >> /tmp/domains/$DOMAIN
domain[$DOMAIN]=1
done < Names.txt
sed -ir "$ s/.,$//" /tmp/domains/*
for i in "${!domain[@]}"; do
echo -n "$i(server:";
while read line ; do
echo -n "$line" ;
done < /tmp/domains/$i
echo ")"
done
rm -rf /tmp/domains
これにより、各ドメインファイル名に含まれるサーバーのリストが含まれるように、次のデータを含む/ tmpフォルダにフォルダが作成されます。
$ ls -lhtr /tmp/domains/
total 12K
-rw-rw-r-- 1 arushirai arushirai 11 Jun 19 17:54 TADDomain
-rw-rw-r-- 1 arushirai arushirai 16 Jun 19 17:54 LinkDomain
-rw-rw-r-- 1 arushirai arushirai 32 Jun 19 17:54 ABCDomain
$ cat /tmp/domains/ABCDomain
ContractABCServer_1,
ABC_server
$ cat /tmp/domains/LinkDomain
CoreLinkServer_
$ cat /tmp/domains/TADDomain
TADServer_
答え4
(正しい出力形式に更新)
使用awk
:
BEGIN { OFS = "," }
{ servers[$1] = (servers[$1] == "" ? "server:" $2 : servers[$1] "," "server:" $2 ) }
END {
$0 = ""
for (domain in servers)
$(++n) = sprintf("\"%s(%s)\"", domain, servers[domain])
print
}
これにより、入力ファイルを解析するときに、基本ブロックの特定のドメインにカンマ区切りの文字列としてサーバーが追加されます。これはservers
、特定のドメインのサーバーを保持する配列を変更することによって行われます(ドメインは配列のキーです)。
このEND
ブロックでは、配列内のすべてのキー/フィールドを繰り返し、servers
指定された形式で出力レコードを生成します。
提供されたデータに対して実行:
$ awk -f script.awk names.txt
"TADDomain(server:TADServer_1)","ABCDomain(server:ContractABCServer_1,server:ABC_server1)","LinkDomain(server:CoreLinkServer_1)"
基本的に同等のbash
スクリプト(bash
連想配列の場合は4.3+が必要):
declare -A servers
while read domain server; do
servers[$domain]+="${servers[$domain]:+,}server:$server"
done <names.txt
for domain in "${!servers[@]}"; do
out+="${out:+,}\"$domain(${servers[$domain]})\""
done
printf '%s\n' "$out"
...しかし「参照」シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?」。