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_filename
Supongo que intentaste filtrar ese nombre de archivo (ver las respuestas a continuación para eso)Respuestas:
Deberías usar:
Entonces
maxdepth 1
significa que desea buscar en el directorio actual sin subdirectorios.type f
significa 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
-t
es 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
-name
opción parafind
. Y recuerda citar el patrón.Entonces
fuente
-print0
como último argumento para encontrar (en lugar del predeterminado: -print) y agregar a-0
como 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
find
soluciones, pero otra solución válida es hacer que losmv
comandos sean más granulares.Esto hace 4096 movimientos, con una menor cantidad de archivos movidos por
mv
operació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
,rsync
podría ser una opción más rápida:--inplace
y-W
están configurados para acelerar el proceso.Si esto produce otro error de lista de argumentos demasiado largo, entonces podría alimentar listas a
rsync
Haga la lista con find, por ejemplo
y dáselo a
rsync
La fuente aquí es
/path/to/files
, porquersync
tratará la lista que le dé como relativa a su fuente.El punto es:
rsync
es 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.txt
y luego pasarla a rsync--files-from=/tmp/my_image_list.txt
. El punto es quersync
es más rápido. A menos que los archivos residan en el mismo sistema de archivos, que OP no ha indicado.