Estoy copiando archivos de la carpeta src a la carpeta de destino usando el comando:
cp -nv /src/* /dest/ > copy_result.txt
El resultado de los archivos copiados está en el archivo de salida como se muestra a continuación:
« /src/test1.txt » -> « /dest/test1.txt »
« /src/test2.txt » -> « /dest/test2.txt »
De lo contrario, quiero que el archivo de salida contenga solo el nombre del archivo, sin la ruta completa y sin la extensión del archivo, así:
test1
test2
Respuesta1
Prueba el comando
cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
awk
imprime el sexto campo. Y rev
invierte la cuerda. cut
divide la cadena en un delimitador especificado por -d
, extrae la parte especificada por -f
.
Editar:
Como se señaló, esto no es compatible con archivos/directorios con espacios. Pero esto se hará extrayendo subcadenas entre '-> « ' y ' »':
cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
Respuesta2
-v
no está especificado por POSIX. Esto significa que cada cp
implementación puede manejarlo de manera diferente (o no manejarlo en absoluto). Donde tu cp
dice « foo »
mi dice 'foo'
. Es posible crear un comando que transforme el resultado no deseado en el deseado; aun así, me gustaría presentar una solución independiente de cp
la implementación.
Después de /src/*
que su comando se expanda, cp
copie las entradas resultantes una por una. Esto significa que puedes convertirte cp -n /src/* /dest/
en
for file in /src/*; do cp -n "$file" /dest/; done
Ahora es fácil hacer algo con $file
. Esto generará el resultado que desea:
for path in /src/*; do
file="${path##*/}"
dst="/dest/$file"
[ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done
(Para redirigir a copy_result.txt
usar done > copy_result.txt
en lugar de solo done
).
Tenga en cuenta que si usó cp -r -v
y al menos uno de los operandos de la expansión de /src/*
era un directorio, cp
copiaría e imprimiría su contenido, mientras que el código anterior (después de agregar -r
) copiaría tanto pero imprimiría solo el directorio en sí. -r
Puede que no sea la única opción que introduciría discrepancia.
Entonces, si bien el enfoque debe ser independiente de cp
la implementación, depende de que algunas opciones no se utilicen. Otra desventaja es que el código ejecuta un cp
proceso separado para cada objeto /src/
, lo que está lejos de ser óptimo.
También hay una condición de carrera: si el $dst
archivo aparece entre [
y cp
, cp
hará su trabajo. Puede utilizarlo cp -n
para evitar la sobrescritura, pero printf
aún así informará el archivo.