删除部分字符串使用sed
问题描述:
我有一个看起来像这样的数据线:删除部分字符串使用sed
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
答
cut
是一个更适合。
cut -d_ -f 1-4 old_file
这仅仅意味着使用_作为分隔符,并保留字段1-4。
如果你坚持sed
:
sed 's/\(_[^_]*\)\{4\}$//'
这左手边匹配一组恰好四个重复,组成一个下划线后跟0或多个非下划线的。在那之后,我们必须处于最后。这全部被没有取代。
答
sed -e 's/_[0-9][0-9]*_[+-]_contigs_full.fasta$//g'
尽管如此,缩减的答案可能更快,通常会更好。
答
是的,剪切方式更好,并且匹配每个背面都比较容易。
我终于得到了使用每一行的开头匹配:
sed -r 's/(([^_]*_){3}([^_]*)).*/\1/' oldFile > newFile
答
sed -e 's/\([^_]*\)_\([^_]*\)_\([^_]*\)_\([^_]*\)_.*/\1_\2_\3_\4' infile > outfile
匹配“任意数量的不是‘_’”,节约了什么\(和\)之间的匹配,其次是'_'。做4次,然后匹配其余部分的任何内容(被忽略)。用'_'分隔的每个匹配代替。
答
这里的另一种可能性:
sed -E -e 's|^([^_]+(_[^_]+){3}).*$|\1|'
其中-E,像GNU -r战略经济对话开启的可读性扩展正则表达式。
只因为你可以在sed中做它,但并不意味着你应该。我喜欢为此更好地剪切。
答
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"}'