Tengo millones de archivos con la siguiente nomenclatura en una máquina Linux:
1559704165_a1ac6f55fef555ee.jpg
Los primeros 10 dígitos son marcas de tiempo y los seguidos por un _son identificadores específicos. Quiero mover todos los archivos que coincidan con identificadores de nombre de archivo específicos a una carpeta diferente.
Intenté esto en el directorio con archivos
find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"
Sin embargo, recibo un error que indica:
bash 1559704165_a1ac6f55fef555ee.jpg: command not found
Cuando lo intenté, mv ??????????_a1ac*.jpg recibo una lista de argumentos de error demasiado largo. Tengo al menos 15 patrones de nombre de archivo diferentes. ¿Cómo los muevo?

| ??????????_a1ac*.jpg:: bash lo expande a varios nombres de archivo, el primero es1559704165_a1ac6f55fef555ee.jpg, si termina , en esa segunda etapa de canalización, intentando ejecutar:.1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filenameSupongo que intentaste filtrar ese nombre de archivo (ver las respuestas a continuación para eso)Respuestas:
Deberías usar:
Entonces
maxdepth 1significa que desea buscar en el directorio actual sin subdirectorios.type fsignifica buscar solo archivos.name '??????????_a1ac*.jpg'es un patrón que coincide con el archivo que está buscando.mv -t destination "{}" +significa mover archivos coincidentes al destino. Aquí+agrega nuevos archivos coincidentes a los anteriores, como:Aquí abcd son diferentes archivos.
fuente
-tes una extensión GNU y, por lo tanto, puede no estar disponible en otros tipos de derivados de UNIX."{}", en cuyo caso quiero señalar que{}el shell no expande y no necesita ser citado. El shell pasa{}a buscar, y encuentra ve{}y lo reemplaza con nombres de ruta. Find exec no utiliza el analizador de shell y no divide las palabras por sí mismo. Citarlo no hace ningún daño, es solo que la justificación dada es un poco inexacta.Tu orden
¡Canaliza la lista de todos los archivos A todos los archivos!
Hará el truco.
fuente
Estas muy cerca. Debe usar la
-nameopción parafind. Y recuerda citar el patrón.Entonces
fuente
-print0como último argumento para encontrar (en lugar del predeterminado: -print) y agregar a-0como la primera opción para xargs (es decir:)xargs -0 mv -t "/home/ubuntu/ntest". de esa manera, se pueden manejar todo tipo de nombres de archivo extraños (con espacios en él, con "nueva línea", etc.).find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest"(Sin embargo, solo funciona con hallazgos similares a GNU)No es tan "bueno" como las
findsoluciones, pero otra solución válida es hacer que losmvcomandos sean más granulares.Esto hace 4096 movimientos, con una menor cantidad de archivos movidos por
mvoperación.fuente
find(por cualquier razón).Si desea mover archivos en el mismo sistema host, lo que supongo que está haciendo con su
mv,rsyncpodría ser una opción más rápida:--inplacey-Westán configurados para acelerar el proceso.Si esto produce otro error de lista de argumentos demasiado largo, entonces podría alimentar listas a
rsyncHaga la lista con find, por ejemplo
y dáselo a
rsyncLa fuente aquí es
/path/to/files, porquersynctratará la lista que le dé como relativa a su fuente.El punto es:
rsynces más rápido quemv, si los archivos no están en el mismo sistema de archivos .fuente
find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txty luego pasarla a rsync--files-from=/tmp/my_image_list.txt. El punto es quersynces más rápido. A menos que los archivos residan en el mismo sistema de archivos, que OP no ha indicado.