Как объединить файлы с одинаковым началом имени? - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть каталог с несколькими сотнями файлов * .fasta, например:

Bonobo_sp._str01_ABC784267_CDE789456.fasta
Homo_sapiens_cc21_ABC897867_CDE456789.fasta
Homo_sapiens_cc21_ABC893673_CDE753672.fasta 
Gorilla_gorilla_ghjk6789_ABC736522_CDE789456.fasta
Gorilla_gorilla_ghjk6789_ABC627190_CDE891345.fasta
Gorilla_gorilla_ghjk6789_ABC117190_CDE661345.fasta

и т. Д.

Я хочу объединить файлы, принадлежащие к одному и тому же виду, поэтому вв этом случае Homo_sapiens_cc21 и Gorilla_gorilla_ghjk6789.

Почти у каждого вида есть разное количество файлов, которые мне нужно объединить.

Я знаю, что я мог бы использовать простой цикл в unix / linux, например:

    for f in thesamename.fasta; do
        cat $f >> output.fasta
    done

Но я не знаю, как указать в цикле, как он должен распознавать только файлы с одинаковым началом.Делать это вручную не имеет смысла с сотнями файлов.

Кто-нибудь знает, как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Я предполагаю, что логика именования заключается в том, что виды - это первые три слова, разделенные подчеркиванием.Я также предполагаю, что в именах файлов нет пробелов.

Возможной стратегией может быть получение списка всех видов, а затем объединение всех файлов с этим спецификацией / префиксом в один:

for specie in $(ls *.fasta | cut -f1-3 -d_ | sort -u)
do
    cat "$specie"*.fasta > "$specie.fasta"
done

В этом коде вы перечисляете все файлы fasta, вырезаете идентификатор вида и генерируете уникальный список видов.Затем вы просматриваете этот список и, для каждого вида, объединяете все файлы, начинающиеся с этого идентификатора вида, в один файл с именем образца.

Более надежные решения могут быть написаны с использованием find и избеганием ls, но они более многословны и потенциально менее ясны:

while IFS= read -r -d '' specie
do
    cat "$specie"*.fasta > "$specie.fasta"
done < <(find -maxdepth 1 -name "*.fasta" -print0 | cut -z -f2 -d/ | cut -z -f1-3 -d_ | sort -zu)
0 голосов
/ 06 декабря 2018

Как указано в моем комментарии выше, если вы знаете все свои базовые имена и не против их явного ввода, простое решение будет

for f in Homo_sapiens_cc21_*.fasta; 
    do cat $f >> Homo_sapiens_cc21.fasta; 
done

Поскольку это не так, вам нужно найтиОбщий шаблон, по которому группируется вывод.Из ваших примеров (РЕДАКТИРОВАТЬ: и вашего комментария) я выгляжу так, как будто это может быть три раза в слове с последующим подчеркиванием.

Если предположить, что этот шаблон правильный, то это, вероятно, сделает то, что вам требуется:

for f in *.fasta; 
    do cat $f >> $(echo $f | awk -F'_' '{print $1"_"$2"_"$3".fasta"}'); 
done

Объяснение:

  1. Список всех *,fasta файлов
  2. Создание имени файла из префикса.Мы делаем это, пропуская awk, приказывая разделить входные данные на _ (-F'_') и соединяя их вместе ('{print $1"_"$2"_"$3".fasta"}')
  3. Наконец мы cat текущий файл иперенаправить вывод на вновь созданное имя файла
...