次の行を含むファイルがあります。
1 a
2 a
3 a
1 b
2 b
1 c
2 c
3 c
4 c
1 d
私が得たい結果は次のとおりです。
a 1 2 3
b 1 2
c 1 2 3 4
d 1
答え1
使用awk
:
awk '{ group[$2] = (group[$2] == "" ? $1 : group[$2] OFS $1 ) }
END { for (group_name in group) print group_name, group[group_name] }' inputfile
これにより、グループは名前付き配列に保存されますgroup
。配列はグループ名(入力データの2番目の列)でインデックス付けされ、入力の各行に対してinputfile
最初の列の値が正しいグループに追加されます。
このEND
ブロックは、収集されたすべてのグループを繰り返して、グループ名とそのグループの項目を出力します。
このawk
プログラムはより良いレイアウトを持っています:
{
group[$2] = (group[$2] == "" ? $1 : group[$2] OFS $1 )
}
END {
for (group_name in group)
print group_name, group[group_name]
}
これはいいえgroup
アレイが実際に大量のデータを保存している場合はどうすればよいですか?みんなファイルから読み取った入力データです。
大規模データの場合、入力は次のようになります。ソート済みグループ名(2番目の列)には、次を使用します。
awk '$2 != group_name { if (group != "") print group_name, group; group = ""; group_name = $2 }
{ group = (group == "" ? $1 : group OFS $1) }
END { if (group != "") print group_name, group }' inputfile
これは、現在のグループが何であるかを追跡し、そのグループに関するデータを収集します。入力の2番目の列が別の値に切り替えられるたびに、収集されたグループデータを出力して新しいデータ収集を開始します。これは、入力データセット全体ではなく数行の入力のみが保存されることを意味します。
最後のawk
プログラムのレイアウトが良いです。
$2 != group_name {
if (group != "")
print group_name, group
group = ""
group_name = $2
}
{
group = (group == "" ? $1 : group OFS $1)
}
END {
# Output last group (only), if there was any data at all.
if (group != "")
print group_name, group
}
答え2
この試み、
for i in `awk '!a[$2]++ { print $2}' file.txt`
do
echo "$i `awk -v z=$i '$2==z{print $1}' file.txt | tr '\n' ' '`"
done
awk '!a[$2]++ { print $2}
列 2 の固有値を提供します。$2==z{print $1}
変数$ 2のすべての値を等しく印刷しますz
。
答え3
注文する:for i in a b c d; do echo $i;awk -v i="$i" '$2 == i{print $1}' filename| perl -pne "s/\n/ /g";echo " "| perl -pne "s/ /\n/g";done| sed '/^$/d'| sed "N;s/\n/ /g"
出力
for i in a b c d; do echo $i;awk -v i="$i" '$2 == i{print $1}' l.txt | perl -pne "s/\n/ /g";echo " "| perl -pne "s/ /\n/g";done| sed '/^$/d'| sed "N;s/\n/ /g"
a 1 2 3
b 1 2
c 1 2 3 4
d 1