File.txt
chocolate,Paris,ER
milkchocolat,France,FR
berriesnoire,Paris,FR
chocolatewhite,Paris,FR
darkchocolat,Italy,IL
orange,usa,USA
plume,Paris,FR
milkshake,France,FR
orangebark,usa,USA
期望输出:
ber,Paris
cho,Paris
dar,Italy
mil,France
ora,usa
plu,paris
cat file.txt | awk -F”,” ‘{print $1”,”$2}’ | cut -c-3 | sort -u
此命令它只给我输出中的第一列
当前输出:
ber
cho
dar
mil
ora
plu
答案 0 :(得分:3)
使用GNU sed进行排序:
sed -E 's/(...)[^,]*/\1/; s/,[^,]*$//' File.txt | sort -u
输出:
ber,Paris cho,Paris dar,Italy mil,France ora,usa plu,Paris
答案 1 :(得分:3)
对于每一行,将前三个字母与它们在数组记录中的出现次数相关联,并使用它来抑制重复项。因此,打印每个唯一记录的前三个字母和第二个字段。
awk 'BEGIN{FS=OFS=","} !seen[key=substr($1,1,3)]++{print key,$2}' file | sort
给出示例输入,输出如下:
ber,Paris
cho,Paris
dar,Italy
mil,France
ora,usa
plu,Paris
或者,使用任何sed和sort:
sed 's/\(...\)[^,]*\(,[^,]*\).*/\1\2/' file | sort -u
请注意,只有第一个字母的前三个字母是唯一的,第一个字母才会列出该记录。但是,如果第一列的前三个字母和整个第二列都是唯一的,则第二个将列出一条记录。
对于这样的输入:
chocolate,Paris
chocolate,paris
第一个人的输出将是:
cho,Paris
但第二个人的输出将是:
cho,Paris
cho,paris
由于您不清楚,我为这两种情况添加了解决方案,请使用满足您要求的解决方案。
答案 2 :(得分:3)
这是我的:
awk -F, '{printf "%.3s,%s\n", $1, $2}' data.txt | sort -u
答案 3 :(得分:1)
简单的 awk | 排序解决方案:
$ time awk -F, -v OFS=, '{ print substr($1, 1, 3), $2 }' file | sort -u
ber,Paris
cho,Paris
dar,Italy
mil,France
ora,usa
plu,Paris
real 0m0.007s
user 0m0.003s
sys 0m0.006s
我认为通过执行 awk 中的 -u 部分来保存IO会更快,但它等效或慢一点:
$ time awk -F, -v OFS=, -v SUBSEP=, '
BEGIN { split("", a) }
{ a[substr($1, 1, 3), $2] = "" }
END { for (i in a) print i }
' file | sort
ber,Paris
cho,Paris
dar,Italy
mil,France
ora,usa
plu,Paris
real 0m0.007s
user 0m0.006s
sys 0m0.004s
但是在具有asorti()
实现的 awk 版本中,放弃管道并完成整个过程要快一些:
$ time gawk -F, -v OFS=, -v SUBSEP=, '
BEGIN { split("", a) }
{ a[substr($1, 1, 3), $2] = "" }
END { N = asorti(a); for (i=1; i<=N; ++i) print a[i] }
' file
ber,Paris
cho,Paris
dar,Italy
mil,France
ora,usa
plu,Paris
real 0m0.006s
user 0m0.000s
sys 0m0.006s
所以,这取决于您...第一个解决方案是最简单的,并且可以说是最灵活的,因为如果我们想要一个稍微不同的实现(例如,按第二列排序或更改{{ 1}})非常简单,因为管道中两个工具之间的关注点很好地分开了。但是,如果我们担心内存和速度,则可能要考虑最后一个解决方案。
注意:
substr()
,每个实现相对于彼此的结果是相似的。