给定一个这样的文件:
1,768,12,46576457,7898
1,123,435,134,146
2,345,6756856,12312,1311
5,234,567465,12341,1341
1,3245,4356345,2442,13
9,423,2342,121,463
9,989,342,121,1212
我想列出所有行(在 bash 终端中),以便第 1 列中的值至少出现两次(在第 1 列中)。结果应该是
1,768,12,46576457,7898
1,123,435,134,146
1,3245,4356345,2442,13
9,423,2342,121,463
9,989,342,121,1212
答案1
要尝试避免将整个文件存储在内存中,您可以这样做:
awk -F , '
!count[$1]++ {save[$1] = $0; next}
count[$1] == 2 {
print save[$1]
delete save[$1]
}
{print}'
答案2
Perl解决方案:
perl -F, -ane ' $h{ $F[0] } .= $_
}{
$h{$_} =~ tr/\n// >= 2 and print $h{$_} for keys %h
' < input-file
-n
逐行读取输入-a
将 上的每一行-F
(即逗号)分割到@F
数组中。- 行存储在
%h
由第一个字段 ($F[0]
) 键入的哈希中。它们连接在一起(.=
)。 - 在文件末尾(“Eskimogreeting”
}{
),我们循环遍历键并计算换行符的数量(使用tr
运算符)。如果至少为 2,我们将打印存储的行。
| sort -n
如果您希望第一列按数字排序,您可以将输出提供给。
注意力:如果最后一行没有以换行符结尾,则其组将报告其大小 - 1。您可以在chomp
每一行中自行添加换行符来修复它,或者使用行数组数组而不是字符串数组。
答案3
使用 awk(用于多维数组的 GNU awk)
gawk -F, '
{ line[NR] = $0; count[$1]++; found[$1][NR] = 1}
END {
for (id in count)
if (count[id] > 1)
for (nr in found[id])
print line[nr]
}
' file
输出的顺序可能与输入文件的顺序不同。
答案4
使用Python 3:
#!/usr/bin/env python3
import sys
from collections import defaultdict
column_delimiter = sys.argv[1]
column = int(sys.argv[2]) - 1
records = defaultdict(list)
for l in sys.stdin:
l = l.rstrip('\n')
r = l.split(column_delimiter)
records[r[column]].append(l)
for ll in records.values():
if len(ll) > 1:
print(*ll, sep='\n')
用法:
python3 duplicate-columns.py COLUMN-DELIMITER COLUMN
例子:
python3 duplicate-columns.py ',' 1 < data.csv