У меня есть каталог с кучей файлов Ex:

ExperimentA_Rep1.bed
ExperimentA_Rep2.bed
ExperimentA_Rep3.bed
ExperimentB_Rep1.bed
ExperimentD_Rep1.bed
ExperimentC_Rep1.bed
ExperimentC_Rep2.bed
.
.
.
ExperimentZ_Rep5.bed

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

Т.е.

cat ExperimentA_Rep1.bed ExperimentA_Rep2.bed > ExperimentA_merged.bed

Если эксперимент имеет только 1 копию, он не должен ничего делать. Но я не могу жестко закодировать это, это должно быть применимо для любого набора данных экспериментов.

Если бы я запустил скрипт на python, это было бы хорошо.

1 ответ1

0

Попробуйте этот сценарий оболочки:

for f in *Rep1.bed
do
    cat "${f%Rep1.bed}"*.bed >"$f.merged"
done

Как это устроено

Каждый эксперимент в вашем примере имел один файл, имя которого заканчивалось на Rep1.bed . Чтобы найти все файлы в этом эксперименте, мы можем использовать глобус ${f%Rep1.bed}"*.bed . Эти файлы затем объединяются в один файл. Это повторяется для каждого эксперимента.

Форма ${f%Rep1.bed} является примером удаления суффикса. Он принимает переменную f и удаляет из конца любое вхождение шаблона, следующего за знаком % . Например, давайте создадим переменную оболочки:

$ f=ExperimentC_Rep2.bed
$ echo "${f}"
ExperimentC_Rep2.bed

Теперь давайте удалим .bed с конца:

$ echo "${f%.bed}"
ExperimentC_Rep2

Или, как нам нужно, мы можем удалить более длинную строку Rep2.bed:

$ echo "${f%Rep2.bed}"
ExperimentC_

То, что осталось выше, это название эксперимента с удаленным номером репликанта. Мы можем использовать это, чтобы выбрать все репликантные файлы, связанные с этим именем эксперимента, используя глобус "${f%Rep1.bed}"*.bed

Одной строкой

При интерактивном запуске кода иногда проще запустить его одной строкой. Приведенный выше код в виде одной строки:

for f in *Rep1.bed; do cat "${f%Rep1.bed}"*.bed >"$f.merged"; done

Создание объединенного файла только для экспериментов с двумя или более репликантами

В некоторых экспериментах есть только один репликант (*_Rep1.bed). У других есть несколько: _Rep1.bed , _Rep2.bed , .... Если мы хотим выбрать только файлы, у которых есть два или более, мы можем выбрать только файлы, для которых существует Rep2 :

for f in *Rep2.bed; do cat "${f%Rep2.bed}"*.bed >"$f.merged"; done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .