用Sed删除字符串的部分

时间:2010-06-24 02:11:01

标签: linux bash unix 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

6 个答案:

答案 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