Удаление частей строки с 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
11
задан neversaint 24 June 2010 в 02:11
поделиться

6 ответов

cut подходит лучше.

cut -d_ -f 1-4 old_file

Это просто означает использование _ в качестве разделителя и сохранение полей 1-4.

Если вы настаиваете на sed:

sed 's/\(_[^_]*\)\{4\}$//'

Эта левая часть соответствует ровно четырем повторениям группы, состоящей из подчеркивания, за которым следует 0 или более не подчеркиваний. После этого мы должны оказаться в конце строки. Все это заменяется ничем.

27
ответ дан 3 December 2019 в 01:29
поделиться
sed -e 's/_[0-9][0-9]*_[+-]_contigs_full.fasta$//g'

Тем не менее, ответ cut, вероятно, быстрее и в целом лучше.

2
ответ дан 3 December 2019 в 01:29
поделиться

Вот еще одна возможность:

sed -E -e 's|^([^_]+(_[^_]+){3}).*$|\1|'

где -E, как -r в GNU sed, включает расширенные регулярные выражения для удобства чтения.

Однако то, что вы можете сделать это в sed, не означает, что вы должны . Для этого мне гораздо больше нравится резать.

3
ответ дан 3 December 2019 в 01:29
поделиться

Да, крой намного лучше, и да, сопоставить обратную сторону каждого проще.

Я наконец-то нашел совпадение, используя начало каждой строки:

 sed -r 's/(([^_]*_){3}([^_]*)).*/\1/' oldFile > newFile
2
ответ дан 3 December 2019 в 01:29
поделиться
sed -e 's/\([^_]*\)_\([^_]*\)_\([^_]*\)_\([^_]*\)_.*/\1_\2_\3_\4' infile > outfile

Сопоставить "любое число не" _ ", сохраняя совпадение между \ (и \), за которым следует '_'. Сделайте это 4 раза, затем сопоставьте что-нибудь с остальной частью строки (игнорировать). Замените каждое совпадение, разделенное знаком «_».

3
ответ дан 3 December 2019 в 01:29
поделиться

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"}'
3
ответ дан 3 December 2019 в 01:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: