Разделить файл по хромосоме (заголовок строки) на новые файлы

#bash

Вопрос:

У меня есть файл .txt, который выглядит так:

 chr1
       -0.0040129697
       -0.0039704541
      ... (around 1,000 more numbers)
chr2
       0.0036610729
       0.0026386990
      ...
chr3
       -0.0001457086
       0.0006073254
      ...
 

и так далее для чисел 1-22 (таким образом, все 22 хромосомы находятся в этом файле). Я хочу разделить этот файл на 22 файла на основе данных для каждой хромосомы, чтобы файл для chr1 выглядел так:

  -0.0040129697
 -0.0039704541
 ... (more numbers)
 

только записи между chr1 и chr2 содержали, но не фактические заголовки строк «chr1» и «chr2». Я бы предпочел сделать это на bash (т. Е. с помощью awk), но могу сделать это и на каком-нибудь другом языке.

До сих пор я пробовал использовать awk, где, если я сделаю это в формате

 awk '/chr1/,/chr2/' gwe.txt > chr1.txt
 

Он работает, но содержит «chr2» в новом файле, а также включает данные для любых других чисел, которые включают 1 или 2 (например 10,11,…,20,21,22). Для более поздних нуберов это работает, но, как я уже сказал, сохраняет последнюю строку «chr#», которую я могу легко решить, удалив ее. Моя проблема в том, что я изо всех сил пытаюсь превратить это в цикл for, так как я не уверен, как сделать что-то подобное в awk:

for num in {1..21}; do awk '/chr${num}/,/chr${num 1}/' gwe.txt > chr${num}.txt; done так как я получаю ошибку в части ${num 1}.

Ответ №1:

Я предлагаю с awk :

 awk '$1 ~ /^chr/{close(name); name=$1; next} {print $1 >name}' file
 

Ответ №2:

Вероятно, вы бы использовали csplit

https://man7.org/linux/man-pages/man1/csplit.1.html

 csplit -z myfile.txt /chr/ '{*}' --suppress-matched
 

Ответ №3:

использование awk

Просто сохраните имя файла для строк «заголовка» и распечатайте остальные в этом файле. Имея всего 22 файла, нет необходимости беспокоиться о их явном закрытии.

 awk '/^c/ {file=$1; next} {print >file}'