¿Cómo puedo mover cientos de archivos cuyas palabras clave (ID) de sus nombres de archivo figuran en un archivo de texto?

¿Cómo puedo mover cientos de archivos cuyas palabras clave (ID) de sus nombres de archivo figuran en un archivo de texto?

Necesito mover cientos de archivos cuyo nombre incluye un número de identificación y estos números se enumeran línea por línea en un archivo de texto.

Por ejemplo:

The content of `ID.txt`:

1231245
1435466
3454656
3356646

Archivos que necesito mover:

1231245_134.fasta
1231245_134.dna
1435466_345.fasta
1435466_345.dna
3454656_789.fasta
3454656_789.dna
3356646_104.fasta
3356646_104.dna

Respuesta1

¿Qué tal (si su shell proporciona "sustitución de procesos")?

. <(sed 's/^/echo mv /; s/$/* \/target/' ID.txt)

Elimine el eco si está satisfecho con el resultado.

EDITAR(propuesto por Stéphane Chazelas)

sed 's|.*|mv -- &_* /target/|' ID.txt | sh -v -n

Retire el -nsi está satisfecho con el resultado.

Respuesta2

Suponiendo que los nombres de los archivos no contengan espacios en blanco, nuevas líneas, barras invertidas o comillas, y un shell como ksh, zsh o bash con soporte para la sustitución de procesos, podría hacer:

join -t_ <(printf '%s\n' *_* | sort -t_ -k1,1) <(sort ID.txt) |
  xargs sh -c 'exec mv -- "$@" /target' sh

Respuesta3

  • Puede dar grepel argumento -f FILEpara compararlo con expresiones en FILE, uno por línea.
  • ID.txtdebe modificarse ligeramente sedpara que solo coincida exactamente con lo que desea: a ^al comienzo de cada línea para que el número coincida al comienzo de una línea, y _al final para que a 123no coincida 123123_.
  • ls -1enumerará un archivo por línea.
  • xargs -I FOOBARreemplaza las apariciones de FOOBAR con la línea de entrada en lugar de agregar la línea de entrada.

Entonces:

sed -e 's/^/^/' -e 's/$/_/' /path/to/ID.txt > /tmp/ID_regexp.txt
cd /old/dir
ls -1 | grep -f /tmp/ID_regexp.txt | xargs -I FILE mv FILE /new/dir

Respuesta4

Una bashsolución pura:

while IFS= read -r p; do mv ${p}* /target; done < ID.txt
  • < ID.txtda el archivo como entrada
  • while IFS= read -r psalta a través de las líneas
    • mv ${p}* /targetmueva todos los archivos que comiencen con el número del archivo al /targetdirectorio.

Puede escribir echodelante del mvcomando para controlar qué comandos se ejecutarán:

$ while IFS= read -r p; do echo mv ${p}* /target; done < ID.txt
mv 1231245_134.dna 1231245_134.fasta /target
mv 1435466_345.dna 1435466_345.fasta /target
mv 3454656_789.dna 3454656_789.fasta /target
mv 3356646_104.dna 3356646_104.fasta /target

información relacionada