统计匹配模式的行数,但仅限第一次出现
我有一个文件,里面有很多行和各种内容。有些行是以特定的模式开头的,这种模式可能会重复出现。例如:
some line
some line
this: idA001 text
this: idA002 text
some line
this: idB001 text
this: idA001 text
this: idA002 text
this: idC001 text
...
我想要统计每个以 this: id*
开头的第一次出现的行……
如果我用 cat file | grep "this: " | wc -l
,我会统计到每一次出现……我需要写一个脚本,先过滤出这些行,然后去掉重复的,还是说可以用一条简单的命令在bash里完成?如果需要脚本的话,我更喜欢用Python或者Bash……
4 个回答
-1
这是一个简单的解决方案:
my_words = ['this: id']
a = set()
with open('got.txt') as f:
for line in f:
if any(word in line for word in my_words):
a.add(line)
print len(a)
我做了什么:我把包含'this: id'的行写进了一个集合里。因为集合只包含唯一的值,所以你的问题就解决了。这就是集合的一个实际用途。
1
我们可以用一行代码这样写
len({i for i in file if i.startswith('this :id')})
2
这样做就可以了:
awk '/^this:/ && !seen[$0]++ {a++} END {print a}' file
4
它会计算有多少不重复的行是以 this:
开头的。
2
如果你想用一行命令在bash里做到这一点:
sort < file | uniq | grep "this: " | wc -l
uniq
这个命令可以去掉重复的行。
但是我们想要过滤掉那些不一定相邻的重复行,所以我们首先需要用sort
进行排序。
后面的部分和你原来的命令是一样的。
在最近的*nix系统中(我想这包括你可能会用到的任何系统),你可以把sort
和uniq
的调用合并成一个sort -u
。另外,正如jm666提到的,grep -c
会输出匹配行的数量,而不是匹配的行,所以你不需要wc
。这样整个命令就变成:
sort -u < file | grep -c "this: "
最后一点:如果你只想要以this:
开头的行,而不是包含它的任何行,你可以在你的grep表达式中使用^
这个特殊字符,它只匹配行的开头,像这样:
sort -u < file | grep -c "^this: "