
Quiero copiar todos los archivos y subdirectorios excepto el archivo de datos que denomina *.data a un directorio de destino.
[ichen@ui01 sub_test]$ ls
a.cxx a.data subdir
[ichen@ui01 sub_test]$ ls subdir/
sub_a.cxx sub_a.data
Puede ver que hay 2 archivos de datos en el directorio y subdirectorio externos respectivamente. Usé este comando:
[ichen@ui01 sub_test]$ cp -r !(*.data) ../destination_dir/
El objetivo era copiar todos los archivos excepto *.data al destino, pero no funciona en el subdirectorio:
[ichen@ui01 destination_dir]$ ls
a.cxx subdir
[ichen@ui01 destination_dir]$ ls subdir/
sub_a.cxx sub_a.data
Puede ver arriba que este comando solo funciona en el primer directorio, ¿cómo puedo hacer que funcione en todos los subdirectorios?
Respuesta1
No especifica en su pregunta si es un requisito preservar la estructura del directorio en la copia o si solo necesita una copia de los archivos. Para simplemente copiar todos los archivos que no se llamen *.data, puedes usar esto:
find . -type f ! -name '*.data' | xargs cp -t ../destination_dir/
Por otro lado, si deseas preservar la estructura del directorio, puedes usar algo como esto:
for file in `find . ! -name '*.txt' | sed 's/^.\///'`; do if [ -d "./$file" ]; then mkdir -p "../destination_dir/$file"; else cp "./$file" "../destination_dir/$file"; fi; done
No estoy seguro de si existe una forma más sencilla de hacer esto, pero este comando hace lo siguiente:
Busque todos los archivos y carpetas en el directorio actual o sus subcarpetas que no coincidan con *.data y luego para cada uno:
Pruebe si el archivo es un directorio si es un directorio coincidente en el directorio de destino, o si es un archivo, lo copia en el destino.
Editar: Agregar versión del script de shell:
#!/bin/bash
# Disable shell glob expansion within the script
# Required to stop bash from expndinging the glob in $1
set -f
for file in `find . ! -name $1 | sed 's/^.\///'`
do if [ -d "./$file" ]; then
mkdir -p "$2/$file"
else
cp "./$file" "$2/$file"
fi
done