Eu tenho milhões de arquivos com a seguinte nomenclatura em uma máquina Linux:
1559704165_a1ac6f55fef555ee.jpg
Os 10 primeiros dígitos são de data e hora e os seguidos de a _
são IDs específicos. Quero mover todos os arquivos correspondentes a IDs específicos de nome de arquivo para uma pasta diferente.
Eu tentei isso no diretório com arquivos
find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"
No entanto, estou recebendo um erro indicando:
bash 1559704165_a1ac6f55fef555ee.jpg: command not found
Quando tentei, mv ??????????_a1ac*.jpg
estou recebendo um erro muito longo da lista de argumentos. Eu tenho pelo menos 15 padrões de nome de arquivo diferentes. Como eu os movo.
| ??????????_a1ac*.jpg
:: bash o expande para vários nomes de arquivo, o primeiro é1559704165_a1ac6f55fef555ee.jpg
, e você acaba , em que fase 2a tubo, tentando executar:1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filename
Eu acho que você tentou em vez disso. filtro para que filename (ver respostas abaixo para isso)Respostas:
Você deveria usar:
Isso
maxdepth 1
significa que você deseja procurar no diretório atual sem subdiretórios.type f
significa encontrar apenas arquivos.name '??????????_a1ac*.jpg'
é um padrão que corresponde ao arquivo que você está pesquisando.mv -t destination "{}" +
significa mover arquivos correspondentes para o destino. Aqui+
adiciona novos arquivos correspondentes ao anterior, como:Aqui abcd existem arquivos diferentes.
fonte
-t
é uma extensão GNU e, portanto, pode não estar disponível em outros tipos de derivativos UNIX."{}"
, nesse caso, quero ressaltar que{}
não é expandido pelo shell e não precisa ser citado. O shell passa{}
para encontrar e encontrar vê{}
e o substitui por nomes de caminho. O Find Find não usa o analisador de shell e não faz sua própria divisão de palavras. A citação não causa nenhum dano, é apenas que a justificativa fornecida é um pouco imprecisa.Seu comando,
Apresenta a lista de todos os arquivos para todos os arquivos!
fará o truque.
fonte
Você está muito perto. Você deve usar a
-name
opção parafind
. E lembre-se de citar o padrão.assim
fonte
-print0
como o último argumento à localização (em vez do padrão: -print) e adicionar a-0
como a primeira opção ao xargs (por exemplo:)xargs -0 mv -t "/home/ubuntu/ntest"
. Dessa forma, todos os tipos de nomes de arquivos estranhos (com espaços, com "nova linha", etc.) podem ser manipulados.find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest"
(funciona apenas com GNU-como achado, embora)Não é tão "bom" quanto as
find
soluções, mas outra solução válida é tornar osmv
comandos mais granulares.Isso faz 4096 movimentos, com um número menor de arquivos movidos por
mv
operação.fonte
find
(por qualquer motivo).Se você deseja mover arquivos no mesmo sistema host, o que eu acho que você está fazendo com o seu
mv
,rsync
poderia ser uma opção mais rápida:--inplace
e-W
estão configurados para acelerar o processo.Se isso gerar outro erro da lista de argumentos muito longo , você poderá alimentar listas para
rsync
Faça a lista com find, por exemplo
e dê para
rsync
A fonte aqui é
/path/to/files
, porquersync
tratará a lista que você fornecer como relativa à sua fonte.O ponto é:
rsync
é mais rápido quemv
, se os arquivos não estiverem no mesmo sistema de arquivos .fonte
find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt
e depois passá-la para o rsync--files-from=/tmp/my_image_list.txt
. O ponto é quersync
é mais rápido. A menos que os arquivos residam no mesmo sistema de arquivos, que o OP não indicou.