我有一个由制表符分隔的文件,看起来像这样,大约有12万个条目名为no-dots.txt
cluster0 E:1.2e-12^RecName: Full=Putative tyrosine phosphatase 123R;^Viruses
cluster1 E:1.2e-12^RecName: Full=Putative tyrosine phosphatase 123R;^Viruses
cluster2 E:1.2e-12^RecName: Full=Putative tyrosine phosphatase 123R;^Viruses
到目前为止,我有以下脚本:
readarray -t clusternames_array < clusternames.txt
for name in "${clusternames_array[@]}"
do
grep -w $name **no-dots.txt** | awk -F "\t" '{print $2}' | awk -F '=' '{print $2}' | awk -F ";" '{print $1}' | sed s/{[^{}]*}//g | sort | uniq -c | sort -k 1,1nr | head -n 1 | cut -b 5-8
done
我是grep-ping每个集群(cluster0,cluster1,cluster2,.cluster120000),并试图提取第二列中的信息。
接下来的三个awk步骤和sed步骤简单地减少了
E:1.2e-12^RecName: Full=Putative tyrosine phosphatase 123R;^Viruses
与…有关的东西
Putative tyrosine phosphatase 123R
就我的目的而言,这一步很好。
sort | uniq -c | sort
只是计算每个集群中唯一名称的数量,将它们从升序排序到降序值。
head -n 1
是指我只能继续使用最高出现的名称。
它的输出通常类似于
7 Putative tyrosine phosphatase 123R
由于这种格式设置,我只需使用
cut -b 5-8
提取事件数,cut -b 5-8 --complement
提取最常见条目的名称。
我在for循环中运行它,以便有一个包含12万个数字/名称的列表,我可以简单地将这些数字/名称粘贴到Excel文件中。最终,我希望为每个集群提供一个条目,即使grep什么都找不到。但是,如果此代码的输出为空字符串(据我所知),则不会将其写入生成的列表。我最终得到的文件总是短得多。
如何将脚本更改为包含没有值的行,以便最终得到一个输出文件,其中包含12万个条目?
举个例子,我得到了这样一个文件:
name0
name1
name3
name4
name6
name7
name9
其中省略了name2、name5、name8等,但我希望添加任何占位符来维护每个输出的位置:
name0
name1
NULL
name3
name4
NULL
name6
name7
NULL
name9
发布于 2021-02-09 23:29:01
将此附加到您的loooong命令链中:
| grep . || echo NULL
解释:
command1 || command2
构造只在command1
失败时执行command2
,即返回0.以外的其他内容。
默认情况下,管道(=
如果您的最后一个命令(此处的
grep .
将失败并返回1(失败)。因此,整个管道命令链将被shell视为失败,并且由于||
操作符,shell将执行命令||
。如果您的最后一个命令(
cut -b 5-8
)输出任何内容,那么输出将保持不变:grep .
将充当一个no并返回0(成功),因为它已经找到了一些东西。因此,整个管道命令链将被shell认为已经成功,并且由于||
操作符,echo NULL
将不会被执行。发布于 2021-02-09 23:20:53
就像这样..。
$ awk -F'\t|=|;' '{print $1,$3}' no-dots.txt |
sort | uniq -c | sort -k2 -k1,1nr |
awk '!a[$2]++ {print $2,$3}' |
awk 'NR==FNR{a[$1]=$2; next} {print $1 in a?a[$1]:"NULL"}' - clusternames.txt
不幸的是,您没有可测试的输入数据,因此没有测试。
https://stackoverflow.com/questions/66127872
复制相似问题