%20de%20sus%20nombres%20de%20archivo%20figuran%20en%20un%20archivo%20de%20texto%3F.png)
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 -n
si 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
grep
el argumento-f FILE
para compararlo con expresiones enFILE
, uno por línea. ID.txt
debe modificarse ligeramentesed
para 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 a123
no coincida123123_
.ls -1
enumerará un archivo por línea.xargs -I FOOBAR
reemplaza 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 bash
solución pura:
while IFS= read -r p; do mv ${p}* /target; done < ID.txt
< ID.txt
da el archivo como entradawhile IFS= read -r p
salta a través de las líneasmv ${p}* /target
mueva todos los archivos que comiencen con el número del archivo al/target
directorio.
Puede escribir echo
delante del mv
comando 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