Usando find
:
find . -type f -name '*_*.jpg' -exec sh -c '
for pathname do
newname=${pathname##*/}
newname="${pathname%/*}/${newname%%_*}.jpg"
printf "Would move %s to %s\n" "$pathname" "$newname"
# mv -i "$pathname" "$newname"
done' sh {} +
Isto encontraria os nomes de caminho todos os arquivos regulares dentro ou abaixo do diretório atual cujos nomes correspondem ao padrão dado. Para lotes desses nomes de caminho, é executado um pequeno script de shell que faz um loop sobre os nomes de caminho fornecidos e renomeia os arquivos (a real renomeação é comentada por segurança).
Dado um nome de caminho como ./a/b/c/foo0_some_other_bits.jpg
, o script de shell transformaria isso em ./a/b/c/foo0.jpg
primeiro excluindo os diretórios (produzindo foo0_some_other_bits.jpg
) e, em seguida, excluindo tudo após o primeiro caractere _
e adicionando os diretórios novamente. O bit de diretório do nome do caminho é excluído e substituído apenas no caso de conter um ou vários caracteres _
. Isso é feito usando expansões de parâmetros padrão.
Usando a opção globstar
shell em bash
:
shopt -s globstar # use "set -o globstar" in ksh93, or remove completely in zsh
for pathname in ./**/*.jpg; do
[ -f "$pathname" ] || continue
newname=${pathname##*/}
newname="${pathname%/*}/${newname%%_*}.jpg"
printf "Would move %s to %s\n" "$pathname" "$newname"
# mv -i "$pathname" "$newname"
done
Isso é exatamente equivalente ao comando find
acima, com a única diferença de que ele não encontraria nomes ocultos (adicione shopt -s dotglob
para isso).