请帮助我通过 csv 文件解决此问题。 AWK 或 Sed。
id1,ipadd1,number1
id1,ipadd2,number2
id1,ipadd3,number3
id2,ipadd1,number1
id2,ipadd2,number2
id2,ipadd2,number3
id3,ipadd2,number2
id3,ipadd2,number2
期望的输出:
id1,ipadd1,number1
,ipadd2,number2
,ipadd3,number3
id2,ipadd1,number1
,ipadd2,number2
,ipadd2,number3
id3,ipadd2,number2
ipadd2,number2
答案1
$ awk 'BEGIN{FS=OFS=","} seen[$1]++{$1=""} 1' file
id1,ipadd1,number1
,ipadd2,number2
,ipadd3,number3
id2,ipadd1,number1
,ipadd2,number2
,ipadd2,number3
id3,ipadd2,number2
,ipadd2,number2
答案2
POSIX sed:
sed -e '
x;G
/^\([^,]\{1,\}\),.*\n\1,/!{
g;b
}
g;s/^[^,]\{1,\}//
' file
awk -F ',' -v OFS=, '
prev != $1 {
print
prev = $1
next
}
{$1=""}1
' file
输出:
id1,ipadd1,number1
,ipadd2,number2
,ipadd3,number3
id2,ipadd1,number1
,ipadd2,number2
,ipadd2,number3
id3,ipadd2,number2
,ipadd2,number2
答案3
使用 Miller 将输入读取为一组无标头 CSV 记录,并清空每条记录中的第一个字段(如果它等于前一条记录的第一个字段):
$ mlr --csv -N put 'if (FNR == 1 || $1 != @prev) { @prev = $1 } else { $1 = "" }' file
id1,ipadd1,number1
,ipadd2,number2
,ipadd3,number3
id2,ipadd1,number1
,ipadd2,number2
,ipadd2,number3
id3,ipadd2,number2
,ipadd2,number2
上面仅修改当前记录,如果以前的记录的第一个字段与当前记录的第一个字段相同。如果数据已排序,则具有清除的效果全部重复的第一个字段。如果数据未排序,则仅具有局部效果。
等效awk
代码,但仅支持“简单”CSV 数据(没有嵌入分隔符或换行符的字段):
$ awk -F , 'BEGIN {OFS=FS} { if (FNR == 1 || $1 != prev) prev = $1; else $1 = "" }; 1' file
id1,ipadd1,number1
,ipadd2,number2
,ipadd3,number3
id2,ipadd1,number1
,ipadd2,number2
,ipadd2,number3
id3,ipadd2,number2
,ipadd2,number2