Tengo una carpeta con muchos archivos. Quiero copiar todos los archivos que comienzan con estos nombres (separados por espacios):
abc abd aer ab-x ate
a otra carpeta. ¿Cómo puedo hacer eso?
Respuesta1
Con csh
, tcsh
, ksh93
, bash
, fish
o zsh -o cshnullglob
, puedes usarexpansión de corséyglobopara hacer eso ( --
no es necesario para estos nombres de archivos, pero supongo que son sólo ejemplos):
cp -- {abc,abd,aer,ab-x,ate}* dest/
Si prefiere no usar la expansión de llaves, puede usar un bucle for (aquí sintaxis de estilo POSIX/Bourne):
for include in abc abd aer ab-x ate; do
cp -- "$include"* dest/
done
Si tiene una cantidad muy grande de archivos, esto puede resultar lento debido a la invocación de cp
una vez por inclusión. Otra forma de hacer esto sería completar una matriz e ir desde allí (aquí ksh93
o sintaxis zsh
reciente ):bash
files=()
includes=(abc abd aer ab-x ate)
for include in "${includes[@]}"; do
files+=( "$include"* )
done
cp -- "${files[@]}" dest/
Respuesta2
Una nota sobre la expansión de llaves frente a la globalización.
La expansión de llaves no es global (aunque la distinción no es tan clara en csh/tcsh donde se originó como en otros shells). se realizaantesglobo.
Entonces, cuando lo hagas:
cp {a,b}* /dest
Primero se expande a:
cp a* b* /dest
Eso significa que el shell tendrá que expandir dos globos, es decir, obtener la lista completa de archivos dos veces y ver cuáles coinciden con el patrón dos veces.
Con zsh
, eso también significa que si alguno de los elementos globales no coincide con ningún archivo, se cancela todo el comando (lo que puede solucionar habilitando la cshnullglob
opción para que se comporte como en csh).
Eso también significa que si tienes
cp {a,ab}* /dest
cp
Copiará los ab*
archivos dos veces.
Eso es diferente de:
cp @(a|b)* /dest
de ksh
o bash -O extglob
o zsh -o kshglob
, o
cp (a|b)* /dest
de zsh
. Ahí es sólounoglob, por lo que será más eficiente y los archivos solo se incluirán una vez.
Con zsh
, si tienes la lista de prefijos en una matriz:
prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest
(arriba, los prefijos se tratan como globos). Es decir unir los elementos de los arrays con |
y considerar el resultado como un glob ( ~
).
Si la lista es grande, lo que puede encontrar es que la ejecución cp
falla con un"lista de argumentos demasiado larga"error. En ese caso, puede utilizar zsh
la versión incorporada cp
cargando el zsh/files
módulo ( zmodload zsh/files
).
Respuesta3
Por ejemplo tengo estos archivos en el directorio actual:
1-s2.0-S0038092X0000058X-main.pdf ANNDHW.pdf HPcalculation2 1-s2.0-S0306261999000422-main.pdf ANNlee.pdf HPcalculation3 ANNCanada.pdf HPcalculation HPcalculation4
Quiero mover todos los archivos desde HP a la carpeta:
./NewFolder/
Puedo hacer:
cp ./HP* ./NewFolder/
./HP*
Le diré a Linux que estoy interesado en todos los archivos que comienzan desde HP. Lo contrario es cuando estoy interesado en mover todos los archivos que terminan en.pdf
. Puedo poner*
delante de.pdf
:cp ./*.pdf ./NewFolder/
Respuesta4
simplemente puedes hacer
cp abc* abd* aer* ab-x* ate* DestinationPath
Una solución a su problema extendido puede ser
- poner todos los nombres de archivos en una lista, por ejemplo list0.txt
copiar todo con
cp `cat list0.txt` DestinationPath # No necesita espacios en blanco en los nombres de archivos
o mejor,
mientras lee el archivo -r; hacer cp "$archivo" destino/ ; hecho < lista0.txt
Notas:
- "$file" porque así puedes manejar el nombre con espacios en blanco dentro como
One Package.deb
-r
Te protege de secuencias de escape.-r Barra invertida no actúa como carácter de escape. La barra invertida se considera parte de la línea. En particular, un par de barra invertida y nueva línea no se puede utilizar como continuación de línea.