Digamos que eu tenha uma pasta com centenas ou milhares de arquivos, todos nomeados de acordo com o seguinte esquema:
<random number of variable length>_<date code in YYYYMMDD format>.jpg
Exemplo:
73923_20180927.jpg
4457582_20180927.jpg
...
18733557_20190401.jpg
23573_20190401.jpg
...
O que espero que meu script bash faça é imprimir uma lista desses códigos de data, ou seja
20180927
20190401
...
Parece uma tarefa mais fácil do que é. Como o esquema é sempre o mesmo, já consegui aplicar a manipulação de strings para imprimir apenas a parte necessária dos nomes dos arquivos. No entanto, ainda estou descobrindo como imprimir cada data apenas uma vez.
Existe uma maneira legal de sair disso?
Responder1
Supondo que todos os nomes de arquivos correspondam ao padrão ./*_*.jpg
:
for name in ./*_*.jpg; do
name=${name##*_} # 4457582_20180927.jpg --> 20180927.jpg
printf '%s\n' "${name%.jpg}" # 20180927.jpg --> 20180927
done | sort -u
Isso itera sobre todos os nomes. Para cada nome, ele remove a string de prefixo mais longa correspondente *_
. Em seguida, ele gera a string restante com o .jpg
sufixo removido.
Todas as strings são então classificadas de forma que apenas uma lista de strings exclusivas seja exibida no final.
Se houver risco de o diretório estar vazio, você deve definir a nullglob
opção shell antes do loop ( shopt -s nullglob
). Isso faria com que o loop não fosse executado, em vez de ser executado uma vez com o padrão globbing não expandido em $name
.
Sem nenhuma razão específica, é assim que se faz sem sort
:
declare -A skip=()
for name in ./*_*.jpg; do
key=${name##*_} # 4457582_20180927.jpg --> 20180927.jpg
key=${key%.jpg} # 20180927.jpg --> 20180927
if [[ ! -v skip[$key] ]]; then
printf '%s\n' "$key"
skip[$key]=1
fi
done
Aqui, acompanho quais strings já foram geradas como chaves em uma matriz associativa, skip
. Uma string não será gerada se corresponder a uma chave no array.
Responder2
Supondo que realmente não haja nomes de arquivos impróprios, execute nesse diretório:
ls -U | awk '-F[_.]' '{ print $2 }' | sort | uniq