如您所见,我有一个文件,它是由制表符分隔的数据,大约4,000行,10列。
文件的第二列记录不同的组织。
samples tissue_s tissue_e tissue_d tissue_category tissue_visa sex study tissue_f age
samples1 ear CNS ear CNS CNS male 1 ear 365
samples2 ear CNS ear CNS CNS male 1 ear 365
samples3 ear CNS ear CNS CNS male 1 ear 365
samples4 ear CNS ear CNS CNS male 1 ear 365
samples5 ear CNS ear CNS CNS male 1 ear 365
samples6 stomach CNS ear CNS CNS male 1 ear 365
samples7 stomach CNS ear CNS CNS male 1 ear 365
samples8 stomach CNS ear CNS CNS male 1 ear 365
samples9 stomach CNS ear CNS CNS male 1 ear 365
...
...我希望能把所有出现过十次以上的组织信息打印出来。
但是我认为这样做和生成中间文件是效率低下的。有没有一种更简洁、更有效的方法?
cat file | awk '{print $2}' | awk '{a[$0]++}END{for(i in a){if(a[i] > 10){print i}}}' > tmp.txt
grep -wFf tmp.txt file.txt > resule.txt发布于 2023-02-03 22:00:04
使用Raku (以前称为Perl_6)
~$ raku -e 'my %h; do for lines.skip() {%h.push: .words.[1] => .words}; \
for %h.kv -> $k,@v {(put $k; .put for @v) if @v.elems > 4};' file您可能有兴趣尝试一种Perl-家族语言,即Raku。一个优点是对Unicode内置的高级支持,您应该使用不同的语言排序规则与同事交换数据。
上面声明了一个%h散列,并将自动块lines (skipping标头行)编辑到它上,.words.[1] (第二列)作为键,.words (所有列)作为值。由于%h散列中不存在重复的键,所以在第二列中的每个单独的组织下都会添加行。一旦处理完所有行,哈希将被%h.kv键值处理为标量$k键和数组中的@a值。只打印@v.elems > 4 (即OP的示例输入超过4行)。
样本输入:
samples tissue_s tissue_e tissue_d tissue_category tissue_visa sex study tissue_f age
samples1 ear CNS ear CNS CNS male 1 ear 365
samples2 ear CNS ear CNS CNS male 1 ear 365
samples3 ear CNS ear CNS CNS male 1 ear 365
samples4 ear CNS ear CNS CNS male 1 ear 365
samples5 ear CNS ear CNS CNS male 1 ear 365
samples6 stomach CNS ear CNS CNS male 1 ear 365
samples7 stomach CNS ear CNS CNS male 1 ear 365
samples8 stomach CNS ear CNS CNS male 1 ear 365
samples9 stomach CNS ear CNS CNS male 1 ear 365示例输出(来自上述代码):
ear
samples1 ear CNS ear CNS CNS male 1 ear 365
samples2 ear CNS ear CNS CNS male 1 ear 365
samples3 ear CNS ear CNS CNS male 1 ear 365
samples4 ear CNS ear CNS CNS male 1 ear 365
samples5 ear CNS ear CNS CNS male 1 ear 365调整输出以满足您的需要是相当容易的。如果您不想要一个单独的“组织”头线,请放弃对put $k;的调用。此外,将@a行输出更改为.join("\t").put for @v,以重新构成\t制表符分隔行.
注意,上面的答案假设每个列条目都没有空白,因为.words在空格上拆分(\t与否)。如果不能保证每个列条目都是一个空格分隔的元素,那么请使用.split("\t")。把它们放在一起(给出与上面相同的输出,但现在用制表符分隔):
~$ raku -e 'my \%h; do for lines.skip() {\%h.push: .split("\t").[1] => .split("\t")}; \
for \%h.kv -> $k,@v {($k.put; .join("\t").put for @v) if @v.elems > 4};' filehttps://unix.stackexchange.com/questions/733937
复制相似问题