У меня есть папка с множеством файлов (xyz1, xyz2, вплоть до xyz5025), и мне нужно запустить скрипт для каждого из них, получив xyz1.faa, xyz2.faa и т. Д. В качестве выходных данных.
Команда для одного файла:
./transeq xyz1 xyz1.faa -table 11
Есть ли способ сделать это автоматически? Может быть, комбо?
for file in xyz*; do ./transeq "$file" "${file}.faa" -table 11; done
. Я пишу такие вещи все время. И если вы хотите убедиться, что имена файлов и т. Д. Расширяются так, как вы хотите, просто поставьтеecho
сразу послеdo
первого раза, а затем вернитесь в историю оболочки и удалите ее во второй раз."$file".faa
его немного легче вводить как часть интерактивной однострочной строки, и он безопасен, поскольку.faa
не содержит метасимволов оболочки, которые необходимо заключать в кавычки.xyz*
глобус также подберет файлы .faa. Для bash запуститеshopt -s extglob
( ссылка ), а затем используйте,for file in xyz!(*.faa) ...
чтобы исключить файлы .faa от отправки через цикл.Если вы устанавливаете GNU Parallel, вы можете сделать это параллельно так:
Если ваша программа интенсивно использует процессор, она должна немного ускориться.
источник
Вы можете сделать что-то вроде этого в
bash
командной строке:Мы генерируем целые числа от 1 до 5025, по одной на строку, затем подаем их один за другим в xargs, который инкапсулирует целое число в
{}
и затем трансплантирует его в командную строку ./transeq соответствующим образом.Если у вас нет возможности расширения скобок,
{n..m}
вы можете вызватьseq
утилиту для генерации этих чисел.Или вы всегда можете эмулировать генерацию чисел с помощью:
источник
for i in {1..5025}; do ./transeq "xyz$i" "xyz$i".faa -table 11; done
это гораздо проще думать и печатать. Если вы хотите, чтобы он печатал команды перед их выполнением, используйтеset -x
.for i in
{1..5025}
для достижения точно такого же результата, как ваш. Вы также можете писатьfor ((i=1 ; i<=5025 ; i++)); do ./transeq "xyz$i" "xyz$i".faa -table 11; done
на bash, но я обычно использую{a..b}
синтаксис диапазона, потому что он быстрее печатается.Использование find полезно, когда ваши файлы разбросаны по каталогам
источник
Предполагая, что у вас более одного ядра, и каждый вызов может выполняться независимо от остальных, вы получите значительное ускорение при параллельных запусках.
Относительно простой способ сделать это с помощью
-P
параметраxargs
- например, если у вас есть 4 ядра:-n 1
Говорит ,xargs
чтобы выбрать только один аргумент из списка для каждого вызова (по умолчанию он будет проходить много) , и-P 4
говорит ему , чтобы породить 4 процессов одновременно - когда кто -то умирает, а новая породившие.ИМХО, вам не нужно устанавливать GNU параллельно для этого простого случая -
xargs
достаточно.источник
Ты можешь использовать
xarg
ls | xargs -L 1 -d '\n' your-desired-command
-L 1
вызывает пропуск 1 предмет за раз-d '\n'
сделать вывод изls
split'ed на основе новой строки.источник