我有一张如下表
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
您需要逐行读取文件,并构建一个将水果与列表的店铺号码。您可以使用 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 历史记录扩展
代码:(复制并粘贴到您的 shell 中)
# 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