Você pode usar o operador split+glob
:
find . -name '*.zip' -exec sh -c '
IFS=/ # split on /
set -f # disable glob
for file do
set -- $file # invoke split+glob, store in positional parameters
# now the path components are in $1, $2...
mv -i -- "$file" "someString_${2}_${4}+${6}"
done' sh {} +
$1
teria .
, $2
DE_AT
e assim por diante. Para obter o último argumento, torna-se complicado, pois você precisa de algo como:
eval "last=\${$#}"
Pode ser mais fácil usar um shell diferente, como zsh
, que possui operadores e matrizes apropriados para isso:
find . -name '*.zip' -exec zsh -c '
for file do
components=(${(s:/:)file})
printf "Last component: %s\n" $components[-1]
mv -i -- "$file" "someString_$components[2]_$components[-3]+$components[-1]"
done' zsh {} +
Com zsh
, você também pode usar o zmv
ferramenta de renomeação de lotes:
autoload zmv # best in ~/.zshrc
zmv -n '([^/]#)/**/(*)/*/(*.zip)' 'someString_${1}_${2}+$3'
A parte **/
corresponde a qualquer nível (incluindo 0) dos subdiretórios, portanto corresponderá a (a)/b/c/(d)/e/(f.zip)
ou (a)/(b)/c/(d.zip)
com as sequências capturadas ( a
/ d
/ f.zip
, a
/ b
/ d.zip
) indo em $1
/ $2
/ $3
para a substituição, de modo a obter um comportamento semelhante ao da abordagem da matriz $components
acima.
A parte [^/]#
em que #
é como o operador regexp *
, corresponde a qualquer sequência de não /. Para globs, *
funciona da mesma forma que *
não pode passar um /
, mas depois de expandir o glob, zmv
usa a correspondência de padrões nos arquivos resultantes para extrair as partes para a substituição, e lá, *
iria para um /
, então (*)
no lugar de ([^/]#)
corresponderia muito.