Eu sou muito novo no linux / linha de comando e preciso criptografar os nomes de arquivos de 10K + (nomes exclusivos) para que eles correspondam ao nome criptografado MD5 no banco de dados mySQL.
Eu vi como você pode renomear um diretório de arquivos e como obter o hash de um arquivo ( mdsum? ), Mas estou empolgado em como obter o hash do nome do arquivo e renomeá-lo para manter o hash gerado a extensão ou seja
mynicepicture.jpg > fba8255e8e9ce687522455f3e1561e53.jpg
Parece que deveria ser uma simples renomeação ou mv
linha, mas não consigo entender.
Muito obrigado por suas idéias
PS: Eu já vi o uso de funções Perl em alguns exemplos próximos do que estou procurando, mas não tenho idéia de onde / como usá-los.
command-line
rename
mv
BradH
fonte
fonte
fba8255e8e9ce687522455f3e1561e53
é o hash MD5mynicepicture
, isso significa que a extensão deve ser removida antes do hash?md5sum <<<"file name"
ofile name
arquivo existente ou não, porque é considerado uma string, exceto alimentá-lo com o nome dos arquivos existentes.Respostas:
Você não disse qual shell deseja usar, então estou assumindo o Bash - a resposta precisa de ajustes para funcionar com outros shells.
Versão do script:
Esse
for
loop simples pega todos os arquivos no diretório atual, calcula a soma md5 de seu nome e a gera. Use isso para verificar a funcionalidade, se você deseja começar a renomear, substitua o segundoecho
pormv
.Explicações
echo -n "$i" | md5sum
- calcule a soma md5 do nome completo do arquivo, incluindo a extensão do arquivo ( Piping ), para reduzir a alteração da extensãoecho -n "$i"
para um dos seguintes:sum=$(…)
- execute…
e salve a saída em$sum
( substituição de comando )${sum%% *}
- imprima tudo até o primeiro espaço ( substituição de parâmetro ), o mesmo que um dos seguintes:${i##*.}
- gera tudo após o último ponto (Substituição de parâmetro), o mesmo que um dos seguintes:Se você precisar renomear arquivos recursivamente em pastas diferentes, use
find
com a-exec
opçãofonte
Este
bash
script usa omd5sum
utilitário GNU coreutils para calcular o hash MD5 a partir do nome base (extensão sans) de qualquer nome de caminho. A função auxiliarmd5name
faz o cálculo real e produzirá o novo nome com caminho e extensão completos.A
md5name
função usaawk
para montar o novo nome das partes do nome do caminho fornecido e o resultado demd5sum
.Exemplos da função em uso por si só:
... onde
c9e89fa443d16da4b96ea858881320c9
está o hash MD5 da stringfile name here
.Remova o
echo
script na parte superior para renomear os arquivos. Você pode salvar a saída do script original em um arquivo (com oecho
local), se em algum momento precisar restaurar os nomes dos arquivos em seus originais.Observe que executar isso duas vezes em um conjunto de arquivos calculará o hash MD5 dos hashes MD5 e que o nome do arquivo original se tornará irrecuperável, a menos que você faça anotações cuidadosas sobre quais arquivos são chamados depois de cada execução do script.
fonte
awk
parte pode ser substituída porwhile read sum dummy ; do printf "%s/%s.%s\n' $dir $sum $ext ; done ;
Você precisadummy
capturar o '-'.awk
mim mesmo e levei um tempo para usobash
utilitários em vez desystem()
noawk
Com
perl
'srename
:(remova
-n
quando estiver feliz).fonte
Para uma
AWK
abordagem:find
Comandos modernos não exigem um diretório para a entrada.
é assumida; portanto, o [Diretório] pode ser deixado em branco. O-type f
único encontra arquivos, o que é útil, poismd5sum
não gosta de diretórios e alterar o nome do diretório durante a execução não seria uma boa idéia. Use-iname pattern
se você quiser apenas usar alguns arquivos, por exemplo-iname \*.dat
, se o caso for importante, use em-name
vez de-iname
.As
match(...); sub(...)
peças estão extraindo partes do nome do arquivo e substituindo-as na string de entrada. Observe que"^"
e"$"
[pre / ap] estão pendentes para impedir a substituição de uma sequência que pode repetir o caminho / extensão.Substitua
print(com)
porsystem(com)
para realmente executar a renomeação.Se você deseja usar o
md5sum
arquivo real como um nome, pode usar o fato de quemd5sum
gera a soma e o nome do arquivo de entrada para algo como:O
while read sum file
levará 2 argumentos, os resultados domd5sum
comando e atribuirsum
efile
variáveis com eles. Como o espaçosum
não deve ter espaços, eleread
deve funcionar bem.Obviamente, ele
[echo]
deve ser removido durante a execução, mas é sempre uma boa idéia ao testar qualquer alteração no script para testar a pesquisa antes da execução.Isso tudo pressupõe que você esteja executando
bash
. Além disso, isso pode ser digitado como uma linha longa:fonte
Essa abordagem geralmente gosto de usar.
O comando "ls" produz um fluxo de linhas de texto. O comando "sed" transforma cada linha com regras de correspondência de padrões. O comando "sed" gera um comando "mv" que é então canalizado através de um shell "sh" para execução. Os parâmetros do comando "mv" são como "mv oldfilename newfilename", que renomeia o arquivo. Eu construo o novo nome de arquivo com um comando sed que toma a parte antes do último ponto e o ecoa na entrada do comando "md5sum" e, em seguida, pega apenas o hash da saída.
Percorrendo meu processo, primeiro liste os arquivos ('head -n 3' para ver apenas as 3 primeiras linhas):
Em seguida, pense em transformar com sed (ainda não canalizando nenhum comando gerado por meio de um shell)
Existem três padrões de correspondência:
Eu quero usar sed para substituir um nome de arquivo de entrada por "mv filename NEWfilename", mas como estou canalizando comandos através de um shell, posso gerar comandos que obtêm o md5sum, como este
para obter apenas o hash
Em um shell unix, podemos usar operadores de backtick (`some_command`) para executar um subcomando, portanto, por exemplo
De volta ao comando mv, quero que o sed produza "mv here there" com "there" substituído por um comando backtick para obter o md5sum. A cadeia dentro da cadeia de substituição sed começa assim
Mas está claramente criando o mesmo hash para cada nome de arquivo, pois o comando backticked está sendo executado antes que o sed veja a string. Para impedir que o shell execute o comando backtick para que o sed produza os backticks, precisamos acrescentar barras (também ao caractere de pipe), então novamente:
A saída também precisa que os nomes dos arquivos sejam citados em caso de espaços, portanto
Então, vamos experimentar este, canalizando-o através de um shell:
Funcionou ? eu acho:
Aqui está uma abordagem para verificação cruzada; use a opção "ls" "-i" para gerar o nó i do sistema de arquivos unix (que não muda com "mv"):
Ou, usando o comando "colar" (pacote 'coreutils')
fonte
Eu gosto da resposta de uma linha, mas ela quebra porque analisa o nome do arquivo. Eu também bati um pouco com sha hashes.
Eu acho que ele também retira os arquivos e os coloca na base de onde o comando foi inserido.
Obrigado.
fonte