¿Cómo reemplazar parte de un nombre de archivo con entrada de stdin?

¿Cómo reemplazar parte de un nombre de archivo con entrada de stdin?

Digamos que tengo un archivo ids.txtcon varias entradas como

foo
bar
bam
...

Por ejemplo. Me gustaría usar esto como entrada para ejecutar un comando en algunos archivos que contienen los identificadores en el nombre del archivo como ,,,, ... foo_1.gzy así sucesivamente.foo_2.gzbar_1.gzbar_2.gz

Intenté hacer referencia a la entrada {}porque vi que esto funcionaba con otro comando, así:

cat ids.txt | xargs my.command --input1 {}_1.gz --input2 {}_2.gz 

pero siempre me da este error:

{}_1.gz no such file or directory

¿Hay alguna forma de tratar la entrada catcomo cadenas de caracteres e insertarlas automáticamente en los nombres de archivo de entrada my.command?

El problema también es que my.commandnecesita dos archivos de entrada cada vez, por lo que no puedo usar simplemente una lista con los nombres de archivos reales en lugar del archivo ids.txt.

Respuesta1

Debes usar la -Iopción aquí:

$ cat ids.txt | xargs -I{} echo my.command --input1 {}_1.gz --input2 {}_2.gz 
my.command --input1 foo_1.gz --input2 foo_2.gz
my.command --input1 bar_1.gz --input2 bar_2.gz
my.command --input1 bam_1.gz --input2 bam_2.gz

Alternativamente, use un bucle de shell:

while read id; do 
    my.command --input1 "${id}"_1.gz --input2 "${id}"_2.gz
done < ids.txt

Eso supone que sus ID no tienen espacios en blanco ni barras invertidas. Si es posible, utilice esto en su lugar:

while IFS= read -r id; do 
    my.command --input1 "${id}"_1.gz --input2 "${id}"_2.gz
done < ids.txt

Finalmente, también puedes usar una lista con dos nombres de archivos por línea:

$ cat ids.txt
foo_1.gz foo_2.gz
bar_1.gz bar_2.gz
bam_1.gz bam_2.gz

Ahora:

while read file1 file2; do
    my.command --input1 "$file1" --input2 "$file2"
done < ids.txt

información relacionada