Я пытаюсь создать скрипт, который в цикле for идентифицирует пары файлов в каталоге, а затем выполняет функцию для каждой пары. Парные файлы называются, например, FILENAME_1.fastq и FILENAME_2.fastq, и в каталоге есть несколько пар. Вот некоторые фактические имена файлов на случай, если это имеет значение для функций регулярных выражений:
WT1_0min-SRR9929263_1.fastq
WT1_0min-SRR9929263_2.fastq
WT1_20min-SRR9929265_1.fastq
WT1_20min-SRR9929265_2.fastq
WT3_20min-SRR12062597_1.fastq
WT3_20min-SRR12062597_2.fastq
Можно ли это сделать без предоставления какой-либо информации об имени файла, кроме того, что у него есть пара? Я абсолютно ужасен с функциями регулярных выражений и поиска имен, но ниже моя последняя неудачная попытка.
cd ~/Directory
for file in *.fastq
do
sample=`basename ${file}` #I think needs a modification to subtract the _1 or _2 and then a search function to find the paired files
myfunction \
-1 ${sample}_1.fastq \
-2 ${sample}_2.fastq \
done
Спасибо за любую помощь. Застрял на 2 дня х_х
ОБНОВЛЯТЬ См. этот новый пост, чтобы узнать, как адаптировать ответ xarg для использования с циклом for.
Используйте find
и xargs
и замените echo
командой по вашему выбору:
find . -name '*_1.fastq' -exec basename {} '_1.fastq' \; | xargs -n1 -I{} echo {}_1.fastq {}_2.fastq
Я решил опубликовать это обновление как новый вопрос, так как это действительно отдельная проблема и заслуживает независимого ответа. Я связал новый пост как обновление в моем посте выше.
для учета сценария не все файлы полностью сопряжены, попробуйте
file . -depth 1 type f -not -name ".*" | \
\
gawk 'BEGIN { FS = "_"; } { $ 0 = gensub(/^.+/([^/]+)$/ , "\\1", "1"); }
{ inL[$1$2][substr($3,1,1)] = $0 ; }
END { OFS = ORS = "\0";
for (pfx in inL) {
if (1 in inL[pfx]) && (2 in inL[pfx]) && \
(length(inL[pfx])==2)
{ print inL[pfx][1], inL[pfx][2]; } } }' | \
\
parallel -0 -N 2 -j 1 myfunction -1 '{}' -2 '{}' ;
gnu parallel позволяет экспортировать функции. эта версия кода будет использовать gawk для обработки функций basename и print0. Это также гарантирует, что в конце будут показаны ТОЛЬКО файлы с точными парами 1 + 2, в случае, если есть файлы только с одним из 2 или некоторые файлы даже с «_3.fastq», если вам нужно расшириться до такого область.
Спасибо! Я попытаюсь объединить это с аргументом if/then. Бывают случаи, когда пары не существуют, и эти файлы необходимо передать в другой цикл for. На данный момент я помещаю парные и непарные файлы в отдельные каталоги и имею два независимых скрипта для каждого.
=) также, ваши имена файлов уже ASCII и/или безопасные для SMB? Я вижу, что вы проводите биосеквенирование данных. Если ваша работа занимает больше 200 МБ на одно задание, подумайте о том, чтобы переписать вышеприведенное в mawk вместо gawk (отказ от ответственности: нулевое отношение к автору — мне просто нравится его безумная скорость). Это означает, что нужно обманывать многомерные массивы и обходить gensub. Я переписал свои собственные служебные функции, смешав mawk 1.3, mawk2-beta и gnu-parallel до такой степени, что он превосходит встроенный wc по подсчету строк, превосходит tr и gnu sed по простому регулярному выражению и превосходит python3 по кодированию URL. .
Дополнительная сложность: я использую macOS, а параллельная команда не распознается. Я не уверен, стоит ли устанавливать gnu, или у меня уже есть эквивалентная команда для параллелизма?
@JVGen: я тоже на macOS
. с некоторыми настройками, я думаю, вы можете заставить его работать xargs
В биоинформатике мы используем это все время, когда имеем парный конечный прогон:
parallel --plus echo {} {/_1.fastq/_2.fastq} ::: *_1.fastq
или:
parallel echo {} {=s/_1.fastq/_2.fastq/=} ::: *_1.fastq
Обычно я ввожу имена файлов в цикл for, который добавляет имена выходных файлов, а также передает вывод другой команде. Есть ли способ последовательно предоставить пары в цикл for? Примечание. Есть два входных файла, но выходной файл объединен (поэтому нет обозначений _1 и _2). Я отредактировал свой основной пост, чтобы включить пример цикла for, который я успешно использую, когда у меня есть только 1 входной файл вместо 2.