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:
cp file1 file2 file3...file# target
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 ( cp
cat list.txt new_folder
) ya debería haber funcionado. ¿Por qué? Porque el comando interno cat list.txt
es procesado primero por el shell y se expande en file1 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 cp
trabajar, colocando esa lista donde pertenece en el comando completo. Nuevamente, el comando en sí es esto en estructura:
cp list-of-files target_directory
Es fácil ver cómo todo esto se combina en esta versión:
cp $(<list.txt) new_folder
$()
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 de list.txt
la 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_folder
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
Obviamente, el paso 2 es simplemente el cp
comando 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.