AWK: извлечь столбцы из файла: строки имеют переменные столбцы
У меня есть текстовый файл в следующем формате. Каждая строка имеет переменное количество столбцов.
Файл:
gi|269201691|ref|YP_003280960.1| chromosomal replication initiation protein gi|57651109|ref|YP_184912.1| chromosomal replication initiation protein % 1 0.0 2296 100.0
gi|269201692|ref|YP_003280961.1| DNA polymerase III subunit beta gi|57651110|ref|YP_184913.1| DNA polymerase III subunit beta % 1 0.0 1964 100.0
Полученный файл должен выглядеть следующим образом:
gi|269201691|ref|YP_003280960.1| gi|57651109|ref|YP_184912.1| % 1 0.0 2296 100.0
gi|269201694|ref|YP_003280963.1| gi|57651112|ref|YP_184915.1| % 1 0.0 1767 100.0
Код ниже помогает найти столбцы в каждой строке с шаблоном 'ref'.
awk '{for (i=1;i<=NF;i++) if ($i ~ /ref/) print $i }'
Любые идеи о том, как сделать то же самое?
3 ответа
Я предполагаю, что ваши новые строки были искажены в вашем посте, и что ваш входной файл на самом деле имеет только одну запись в строке. В этом случае, я думаю, это делает то, что вы хотите:
awk -F '[|%]' '{printf("%s|%d|%s|%s|",$1,$2,$3,$4);if($6)printf(" %%%s",$6);printf("\n")}'
Изменить: Хорошо, в свете новых номеров строк, что вы хотите, вероятно, это:
awk -F '[|%]' '{printf("gi|%d|ref|%s|gi|%d|ref|%s| %%%s\n",$2,$4,$6,$8,$10)}'
Для вашего примера это дает мне следующий вывод
gi|269201691|ref|YP_003280960.1|gi|57651109|ref|YP_184912.1| % 1 0.0 2296 100.0
gi|269201692|ref|YP_003280961.1|gi|57651110|ref|YP_184913.1| % 1 0.0 1964 100.0
Это работает путем ручной установки разделителя полей на | или же %. Следовательно, переменное количество слов в описании больше не является проблемой, и мы можем напрямую индексировать нужные поля.
Вот один из способов использования GNU awk
:
awk 'BEGIN { OFS=FS="|" } { for (i=1; i<=NF; i++) if ($i ~ / gi$/) $i = " gi"; if (i = NF) sub(/.*%/," %",$i) }1' file.txt
Вот один из способов использования GNU sed
:
sed 's/|[^|]* gi|/| gi|/; s/\(.*|\).*\(%.*\)/\1 \2/' file.txt
Результаты:
gi|269201691|ref|YP_003280960.1| gi|57651109|ref|YP_184912.1| % 1 0.0 2296 100.0
gi|269201692|ref|YP_003280961.1| gi|57651110|ref|YP_184913.1| % 1 0.0 1964 100.0
Это может работать для вас (GNU sed):
sed 's/\(.*|.*|.*|.*|\)\(.*\)\(\S\+|.*|.*|.*|\)\2%/\1\3%/' file
Если во входном файле есть многострочные записи:
sed 'N;s/\n//;s/\(.*|.*|.*|.*|\)\(.*\)\(\S\+|.*|.*|.*|\)\2%/\1\3%/' file