#bash #loops #for-loop #split #vcf-variant-call-format
#bash #циклы #цикл for #разделение #vcf-variant-call-format
Вопрос:
У меня есть 8 файлов, которые я хотел бы разделить на 5 блоков для каждого файла. Обычно я бы делал это по отдельности, но хотел бы запустить это как цикл. Я работаю в HPC.
Я создал список имен файлов и пометил его «variantlist.txt «. Мой код:
for f in 'cat variantlist.txt'; do split ${f} -n 5 -d; done
Однако это разбивает только конечный файл в variantlist.txt файл, выводящий 5 фрагментов только из окончательной записи.
Даже если я перечисляю файлы по отдельности:
for f in chr001.vcf chr002 ...chr008.vcf ; do split ${f} -n 5 -d; done
Он по-прежнему разбивает конечный файл только на 5 фрагментов.
Не уверен, где я здесь ошибаюсь. Желаемый результат должен составлять 40 фрагментов, по 5 на хромосому. Мы были бы очень признательны за вашу помощь.
Большое спасибо
Комментарии:
1. Не используйте
for f in 'cat variantlist.txt';
. Для получения того же результата попробуйтеlst=( $(<variantlist.txt) ); for f in "${lst[@]}"
илиwhile read f;do ... done<variantlist.txt
или дажеxargs ... < variantlist.txt
.2. @PaulHodges спасибо! Метод cat не так эффективен?
3. Посмотрите на бесполезное использование
cat
наград 😉
Ответ №1:
Разделение заключается в создании каждый раз одного и того же набора файлов и перезаписи предыдущих. Вот один из способов справиться с этим —
for f in $(<variantlist.txt) # don't use cat
do mkdir -p $f.split # make a subdir for the files
( cd $f.split amp;amp; # change into the subdir only in a subshell
split ../$f -n 5 -d # split from there
) # close the subshell, parent still in base dir
done
Или вы могли бы просто сделать это —
while read f # grab each filename
do split $f -n 5 -d # split it
for x in x?? # for each split file
do mv $x $f.$x # rename it to include the parent file name
done
done < variantlist.txt # take names from this file
Это намного медленнее, но не использует вложенные файлы.
Мой любимый, хотя —
xargs -I {} split {} -n 5 -d {} < variantlist.txt
Последний аргумент становится ПРЕФИКСОМ для split
вместо значения по умолчанию x
.
РЕДАКТИРОВАТЬ — с 2 миллиардами строк в файле используйте эту:
for f in $(<variantlist.txt)
do split "$f" -d -n 5 "$f" amp; # run all in background at the same time
done
Комментарии:
1. У вас достаточно места? Требуется сжатие?
2. Я запускаю его в интерактивном режиме на HPC, поэтому обновлю вас, как только это будет сделано. Ошибок пока нет, и он работает дольше, чем раньше, что является хорошим знаком (используя ваш отредактированный метод).
3. все еще выполняется! Не уверен, сколько времени это займет
4. два миллиарда строк займут некоторое время …. вы сначала пробовали это на небольших наборах данных?
5. да, я работал с меньшим набором данных. Еще раз большое спасибо за вашу помощь!
Ответ №2:
При использовании split
-n
swicth определяет количество выходных файлов, на которые разбивается исходный файл…
Вам нужно -l
столько строк, сколько вам нужно, в вашем случае 5:
split -l 5 ${f}
Комментарии:
1. спасибо за ответ. Файл на самом деле содержит 2 миллиарда строк, и я хочу, чтобы из этого было 5 файлов, то есть примерно 400 миллионов строк на файл. Если я напишу: split -l 400000000 $ {f} в цикле, это будет лучше?
2. Да, числа, переданные в
-l
, дадут вам слишком много строк на файл.