Ao ler os tutoriais sobre renomeação de arquivos em lote no bash e usar o sort
comando para classificar o conteúdo do arquivo, não consegui descobrir como combinar os dois.
Eu tenho um diretório cujo conteúdo é classificado usando tags no nome do arquivo, semelhante à maneira como o programa TagSpaces lida com as coisas. Eu adiciono as tags que consigo pensar ao final do nome do arquivo quando o crio ou faço o download. Aqui está um exemplo:
Sunrise (2) #wallpaper #4k #googleimages.jpg
Agora eu quero passar por todos esses arquivos e renomeá-los para que as tags sejam classificadas em ordem alfabética, sem afetar nada antes ou depois das tags (por exemplo, o título da imagem ou a extensão do arquivo). Portanto, o acima se tornaria:
Sunrise (2) #4k #googleimages #wallpaper.jpg
Como eu faço isso? Eu não consigo nem descobrir como passar o nome de um arquivo , e não o conteúdo, para um comando como sort
, cuja saída eu talvez pudesse direcionar mv
.
Respostas:
Teste:
fonte
Se você possui o baseado em perl
rename
(prename
em alguns sistemas), pode fazer uma divisão + classificar as tags usando perl. Por exemplo, dadoentão (com algumas discussões feias para remover e substituir o
.jpg
sufixo)Verificando
Provavelmente, há muito espaço para melhorias - mas espero que isso lhe dê alguma idéia.
fonte
Com
zsh
:(remova o
-n
(funcionamento a seco) se estiver feliz).[^#]#
: 0 ou mais caracteres não # (#
é como*
nos regexps)s: :
dividir no espaçoo
: ordem (classificação)j: :
: junte-se ao espaço.Então, estamos dividindo a parte entre o primeiro
#
(incluído) e o último.
(excluído) no espaço, classifique a lista resultante à qual juntamos novamente o espaço.Recursivamente:
Para permitir espaços nos nomes de tags, poderíamos dividir
#
e aparar espaços finais, classificar e juntar-se a#
:Adicione um
(#qD)
qualificador global se você também deseja processar arquivos ocultos (D
arquivos ot) ou deseja processar arquivos em diretórios ocultos.fonte
Boa pergunta!
Aqui está o meu
bash
script simples para isso:Explicação:
In
afile=( ${file#*)} );
: estamos convertendo a string em uma matriz. Nesse estado, o shell realiza a divisão de palavras com espaços, a menos que você cite a string.Em
${file#*)}
( recortar para o primeiro prefixo ): estamos removendo tudo do início da string até a primeira)
vez que a usamos,shell parameter expansion
pois isso resultará#wallpaper #4k #googleimages.jpg
considerando ofile="Sunrise (2) #wallpaper #4k #googleimages.jpg"
In
${file%%#*}
( corte até o último sufixo ); decapagem começa do fim ao começo da corda até ser#
visto pela última vez. isso resultaráSunrise (2)
Em
${afile[@]%%.*}
( corte até o último sufixo ): o mesmo que acima, a remoção começa do fim ao início da cadeia (aqui em cada matriz indexada) até a última.
vez que é vista. isso resultará#wallpaper #4k #googleimages
, também poderíamos usar${afile[@]%.*}
melhor!In
printf "%s\n" "${afile[@]%%.*}"
: estamos imprimindo os elementos da matriz com novas linhas ([@]
usadas para a matriz indexada), (por que com novas linhas? Porque as classificaremos e devemos dividir os elementos em novas linhas)In
$(sort<(printf "%s\n" "${afile[@]%%.*}"))
: estamos classificando os elementos (ou tags).Em
$(echo $(sort<(printf "%s\n" "${afile[@]%%.*}")))
: o mesmo que acima, mas usamos extraecho
comando para reunir os elementos classificados no linear.possível mesmo também com o uso de duplo
xargs
gosto... |xargs -n1| sort | xargs
.Veja o exemplo abaixo para entender melhor esta etapa:
Finalmente, no final, o
mv
comando está renomeando o$file
para o nome modificado que deveria ser.Ps: remova
echo mv ...
na frente domv
para sair a seco e execute a renomeação real.fonte
Parece um pouco complicado para Bash ser honesto. Não é impossível, mas na minha opinião, você está muito melhor usando uma linguagem criada para programação "real" aqui. Uma solução Bash provavelmente não pode ser mantida. (Não tentando insultar a solução apenas do Bash, acho que a mágica de renomear é realmente incrível)
Dito isto, aqui está uma solução com Ruby. Você pode gravá-lo em um arquivo e, em seguida, apenas executá-lo no seu shell, desde que você tenha o Ruby instalado.
Para executar o script, basta colocá-lo no diretório em que suas imagens estão. Essa solução deve ser bastante resiliente a nomes e marcas de imagens tolas, como
C#
não causará problemas. Dito isto, certifique-se de fazer um backup antes de executar o script. As operações de movimento podem ser tão destrutivas quanto arm
.fonte