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.