Tengo una lista de archivos separados por espacios en un archivo list.txt. Me gustaría copiarlos a una nueva carpeta.
Traté de hacer:
cp `cat list.txt` new_folder
Pero no funcionó.
Cómo harías esto ?
Actualizar:
Gracias por todas sus respuestas muy interesantes. No pedí mucho :)
Después de haber probado la solución anterior por segunda vez, parece que se cpimprimió la ayuda de uso porque la carpeta new_folderaún no existía. Lo siento, parece ser un error estúpido ... Cuando creo la carpeta antes, funciona.
Sin embargo, he aprendido mucho de todas sus respuestas y soluciones, gracias por el tiempo que toma escribirlas.

Respuestas:
Intenta usar xargs:
Actualizar:
Hice esto en OS X, que tiene una versión diferente a las versiones de GNU / Linux. El
xargsque proviene de GNU findutils no tiene-Jpero tiene uno-Ique es similar (como señaló Dennis Williamson en un comentario). La versión OS X de xargs tiene ambos-Iy-Jtienen comportamientos ligeramente diferentes: cualquiera funcionará para esta pregunta original.fuente
xargsno tiene-Jlo-Ique parece hacer lo mismo. ¿Qué versiónxargsy qué sistema operativo / distribución tienes?xargs --versiondevuelve un mensaje de error de uso. Es probable que sea una versión BSD de xargs. El uso de-Iy-Json sutilmente diferentes. Actualizaré mi respuesta con ejemplos bien formateados.-Jy-I:)No es necesario
caten absoluto:O usando opciones largas:
Aquí hay algunas versiones de shell. Tenga en cuenta que algunas variables no están entre comillas o los
forbucles se usan específicamente porque el OP especificó que los nombres de los archivos están delimitados por espacios. Algunas de estas técnicas no funcionarán para la entrada de nombre de archivo por línea en la que los nombres de archivo contienen espacios en blanco.Golpetazo:
o
sh (o Bash):
o
o
o
fuente
-tnecesita enxargs -a list.txt cp -t new_folder?-tes una opción decp. Copia todos los argumentos de origen en el directorio de destino especificado. Aquí, permite especificar el objetivo antes que la fuente que agrega elxargscomando.Tuve una respuesta vergonzosamente redonda aquí antes, pero la respuesta de Denis me recordó que me perdí lo más básico. Entonces, borré mi respuesta original. Pero como nadie ha dicho esto tan básico, creo que vale la pena ponerlo aquí.
La pregunta original es "Tengo un archivo de texto con una lista de nombres de archivos separados por espacios. Cómo puedo copiarlos en un directorio de destino". Al principio, esto puede parecer complicado o complicado, porque cree que de alguna manera tiene que extraer los elementos del archivo de una manera específica. Sin embargo, cuando el shell procesa una línea de comando, lo primero que hace es separar la lista de argumentos en tokens y (aquí está el bit que nadie ha dicho directamente) separa los tokens . (Las nuevas líneas también separan los tokens, razón por la cual la prueba de Doug Harris con una lista separada por una nueva línea tuvo el mismo resultado). Es decir, el shell espera y ya puede manejar una lista separada por espacios.
Entonces, todo lo que necesita hacer aquí es colocar la lista separada por espacios (que ya tiene) en el lugar correcto en su comando. Su comando es una variación de esto:
El único inconveniente es que desea obtener la lista de archivos 1 a # de su archivo de texto.
Como Dennis señala en su comentario, su intento original (
cpcat list.txtnew_folder) ya debería haber funcionado. ¿Por qué? Porque el comando internocat list.txtes procesado primero por el shell y se expande enfile1 file2 file3...file#, que es exactamente lo que el shell espera y quiere en esa parte del comando. Si no funcionó, (1) tenía un error tipográfico o (2) sus nombres de archivo eran algo extraños (tenían espacios u otros caracteres inusuales).La razón por la que todas las respuestas de Dennis funcionan es simplemente que proporcionan la lista necesaria de archivos para
cptrabajar, colocando esa lista donde pertenece en el comando completo. Nuevamente, el comando en sí es esto en estructura:Es fácil ver cómo todo esto se combina en esta versión:
$()hace que el shell ejecute el comando dentro de los paréntesis y luego sustituya su salida en ese punto en la línea más grande. Entonces el shell recorre la línea como un todo. Por cierto,$()es una versión más moderna de lo que ya estaba haciendo con backticks (`). Siguiente:<es un operador de redirección de archivos. Le dice al shell que descargue el contenido delist.txtla entrada estándar. Como el$()bit se procesa primero, esto es lo que sucede en etapas:cp $(<list.txt) new_folder# split line into three tokens: cp, $(<list.txt), new_foldercp file1 file2 file3...file# new_folder# substitute result of $(<list.txt) into the larger commandObviamente, el paso 2 es simplemente el
cpcomando normal que deseabas.Me doy cuenta de que estoy golpeando mucho a este caballo (quizás muy muerto), pero creo que vale la pena hacerlo. Comprender exactamente cómo el shell procesa un comando puede ayudarlo a escribirlo mejor y simplificar mucho. También le mostrará dónde es probable que se oculten los problemas. En este caso, por ejemplo, mi primera pregunta debería haber sido sobre nombres de archivos divertidos o un posible error tipográfico. No se necesitaban acrobacias.
fuente
--parentsindicador. Puede hacerlo detallado-vpara obtener un registro de lo que se copió. Si desea mantener los permisos, necesita la bandera-ao-p. Es decir,cp --parents -av $(<list.txt) new_folder. Todo esto supone que su lista de archivos son realmente todos los archivos, de lo contrario, es posible que también necesite-rque se repita el indicador.--parentsbandera no existe allí. Su versión (derivada de BSD)cpsolo ofrece opciones cortas, no opciones largas al estilo GNU. Para un estilo BSDcp, el indicador de copia recursiva es mayúscula-R, no minúscula.