次の表があります
fruits shopname
Apple x1
orange x1
banana x2
Apple x3
orange x2
banana x3
列1に基づいてすべての行をグループ化し、重複項目を空白に置き換えたいと思います。
以下のように見えます。
fruits shopname
Apple x1
x3
banana x2
x3
orange x1
x2
コマンドを使用して重複エントリを削除できることを知っていますuniq
。しかし、ここではグループ化し、重複する項目を空白に変更したいと思います。
答え1
ファイルを1行ずつ読み、果物と果物を結合する関数を構築する必要があります。リスト店舗番号。 awkの多次元配列またはGNU awkの配列配列を使用してこれを実行できます。
次に、ファイルを読んだ後、果物を繰り返し、各果物の各店舗の行を印刷します。
私はこの目的でPerlを使いますが、Perlの構文は少し圧倒的です。
perl -lane '
if ($. == 1) {print; next}
push @{$shops{$F[0]}}, $F[1];
}END{
for $fruit (sort {lc $a cmp lc $b} keys %shops) {
$label = $fruit;
for $shop (@{$shops{$fruit}}) {
printf "%s\t%s\n", $label, $shop;
$label = "";
}
}
' file
答え2
私は同じ結果を得るために次の方法を使用しました。
for i in `awk '{print $1}' y.txt| sort| uniq| tr "\n" " "`; do awk -v i="$i" '$1 == i {print $2}' y.txt| sed "1s/.*/$i\t&/g"| sed '/^x/s/.*/\t&/g';done| sed '1i fruits shopname '
出力
fruits shopname
Apple x1
x3
banana x2
x3
orange x1
x2
答え3
努力する:
sort -t $'\t' <(tail -n+2 infile) |awk 'seen[$1]++{ $1="" }1' OFS='\t'
Apple x1
x3
banana x2
x3
orange x1
x2
空の果物の名前が必要な理由を理解していません。必要なデータを照会し、結果を除くすべての項目を空と見なすことができます。
sort -t $'\t' -uk1,1 <(tail -n+2 infile)
Apple x1
banana x2
orange x1
答え4
他のバージョンは sed を使用しますが、最初のバージョンは入力ファイルを生成します。
set +H
このコマンドを実行する前に、bash履歴拡張を無効にしてください。
パスワード:(コピーしてシェルに貼り付け)
# replace comma with tab to enable copy&paste from stackexchange,
# sort the table, write the file
cat <<EOF | tr ";" "\t" |sort > fruits.txt
Apple;x1
orange;x1
banana;x2
Apple;x3
orange;x2
banana;x3
EOF
echo "BEFORE:"
cat fruits.txt
for fruit in $(cut -f1 fruits.txt|sort -u); do sed -i "/$fruit/!b;n;s/^\w\+//" fruits.txt; done
echo "RESULT:"
cat fruits.txt
出力:
BEFORE:
Apple x1
Apple x3
banana x2
banana x3
orange x1
orange x2
RESULT:
Apple x1
x3
banana x2
x3
orange x1
x2