Tengo una carpeta con muchos archivos (xyz1, xyz2, hasta xyz5025) y necesito ejecutar un script en cada uno de ellos, obteniendo xyz1.faa, xyz2.faa, etc. como salidas.
El comando para un solo archivo es:
./transeq xyz1 xyz1.faa -table 11
¿Hay alguna manera de hacer eso automáticamente? Tal vez un combo para hacer?
for file in xyz*; do ./transeq "$file" "${file}.faa" -table 11; done
. Escribo este tipo de cosas todo el tiempo. Y si desea verificar que los nombres de archivo, etc., se expanden de la manera que desea, simplemente coloque unecho
derecho después dedo
la primera vez, y luego regrese a su historial de shell y elimínelo la segunda vez."$file".faa
es un poco más fácil de escribir como parte de una línea interactiva y segura, ya.faa
que no contiene metacaracteres de shell que necesitan ser citados.xyz*
globo también recogerá archivos .faa. Para bash, ejecuteshopt -s extglob
( referencia ), luego usefor file in xyz!(*.faa) ...
para excluir que los archivos .faa se envíen a través del bucle.Si instala GNU Parallel , puede hacerlo en paralelo de esta manera:
Si su programa consume mucha CPU, debería acelerarse un poco.
fuente
Puede hacer algo como esto en una
bash
línea de comando:Estamos generando los enteros del 1 al 5025, uno / línea, luego los alimentamos uno por uno a xargs, que encapsula el entero en
{}
y luego lo trasplanta a la línea de comando ./transeq de manera apropiada.Si no tiene la función de expansión de llaves,
{n..m}
puede invocar laseq
utilidad para generar esos números.O bien, siempre puede emular la generación numérica a través de:
fuente
for i in {1..5025}; do ./transeq "xyz$i" "xyz$i".faa -table 11; done
es mucho más fácil pensar y escribir. Si desea que imprima comandos antes de ejecutarlos, useset -x
.for i in
{1..5025}
para lograr exactamente el mismo resultado que el tuyo. También podría escribirfor ((i=1 ; i<=5025 ; i++)); do ./transeq "xyz$i" "xyz$i".faa -table 11; done
en bash, pero generalmente uso la{a..b}
sintaxis de rango porque es más rápido de escribir.Usando find, útil cuando sus archivos están dispersos dentro de directorios
fuente
Suponiendo que tiene más de un núcleo, y cada invocación puede ejecutarse independientemente del resto, obtendrá una aceleración considerable con ejecuciones paralelas.
Una forma relativamente simple de hacerlo es a través del
-P
parámetro dexargs
, por ejemplo, si tiene 4 núcleos:El
-n 1
le dicexargs
que elija solo un argumento de la lista para cada invocación (por defecto pasaría mucho) , y-P 4
le dice que genere 4 procesos al mismo tiempo: cuando uno muere, se genera uno nuevo.En mi humilde opinión, no es necesario instalar GNU en paralelo para este caso simple - es
xargs
suficiente.fuente
Puedes usar
xarg
ls | xargs -L 1 -d '\n' your-desired-command
-L 1
causa pasar 1 artículo a la vez-d '\n'
la salida dels
make se divide en función de la nueva línea.fuente