我的数据行如下所示:
sp_A0A342_ATPB_COFAR_6_+_contigs_full.fasta
sp_A0A342_ATPB_COFAR_9_-_contigs_full.fasta
sp_A0A373_RK16_COFAR_10_-_contigs_full.fasta
sp_A0A373_RK16_COFAR_8_+_contigs_full.fasta
sp_A0A4W3_SPEA_GEOSL_15_-_contigs_full.fasta
如何使用sed
删除每行第4列(_分隔)后的部分字符串。
最后屈服:
sp_A0A342_ATPB_COFAR
sp_A0A342_ATPB_COFAR
sp_A0A373_RK16_COFAR
sp_A0A373_RK16_COFAR
sp_A0A4W3_SPEA_GEOSL
答案 0 :(得分:25)
cut
更合适。
cut -d_ -f 1-4 old_file
这只是意味着使用_作为分隔符,并保留字段1-4。
如果你坚持sed
:
sed 's/\(_[^_]*\)\{4\}$//'
这个左侧正好匹配一组的四次重复,由一个下划线后跟0个或多个非下划线组成。在那之后,我们必须在最后一行。这一切都没有被替换。
答案 1 :(得分:3)
sed -e 's/\([^_]*\)_\([^_]*\)_\([^_]*\)_\([^_]*\)_.*/\1_\2_\3_\4' infile > outfile
匹配“任意数量的不'_'”,保存\(和\)之间匹配的内容,后跟'_'。这样做4次,然后匹配线的其余部分(被忽略)。用'_'分隔的每个匹配替换。
答案 2 :(得分:3)
这是另一种可能性:
sed -E -e 's|^([^_]+(_[^_]+){3}).*$|\1|'
其中-E,与GNU sed中的-r一样,打开扩展正则表达式以便于阅读。
仅仅因为可以在sed中执行此操作,但并不意味着应该。我喜欢为此做得更好。
答案 3 :(得分:3)
AWK喜欢在这些领域比赛:
awk 'BEGIN{FS=OFS="_"}{print $1,$2,$3,$4}' inputfile
或者更一般地说:
awk -v count=4 'BEGIN{FS="_"}{for(i=1;i<=count;i++){printf "%s%s",sep,$i;sep=FS};printf "\n"}'
答案 4 :(得分:2)
sed -e 's/_[0-9][0-9]*_[+-]_contigs_full.fasta$//g'
答案仍然可能更快,而且通常更好。
答案 5 :(得分:2)
是的,剪切方式更好,并且可以更容易地匹配每个背面。
我终于使用每一行的开头得到一个匹配:
sed -r 's/(([^_]*_){3}([^_]*)).*/\1/' oldFile > newFile