Aqui está outra maneira:
mkdir -p unknown;
for f in *; do
[[ $f =~ \. ]] && mkdir -p "${f##*.}" &&
mv "$f" "${f##*.}"/ ||
mv "$f" unknown/; done
Explicação
-
&&
significa "executar o comando à direita apenas se o comando à esquerda for bem sucedido". -
||
significa "executar o comando à direita apenas se o comando à esquerda falhar". Os dois símbolos combinados podem funcionar como um blocoif/else
. -
mkdir -p unknown;
: crie o diretóriounknown
. O-p
está lá para quemkdir
não reclame se o diretório existir. -
for f in *
: para todos os arquivos e diretórios no diretório atual. -
[[ $f =~ \. ]] &&
: se o nome atual do arquivo / dir contiver um.
, se ele tiver uma extensão, então ... -
mkdir -p "${f##*.}"/
: a construção${var##pat}
removerá a correspondência mais longa depat
do início da variável$var
. Aqui, opat
é qualquer coisa até um ponto, então isso deixará apenas a extensão. Este comando, portanto, cria o diretório da extensão, se não existir. -
mv "$f" "${f##*.}"/
: Omv
move o arquivo para o diretório relevante.|| mv "$f" unknown/;
: se o comando anterior falhou (se este arquivo / diretório) não tiver uma extensão, mova-o paraunknown
.
Observe que isso imprimirá essa mensagem de erro, mas você pode ignorá-la com segurança:
mv: cannot move ‘unknown’ to a subdirectory of itself, ‘unknown/unknown’
Se você precisar mover apenas arquivos e nenhum diretório (os comandos acima também moverão um diretório chamado dir.foo
para foo/
), use isso:
mkdir -p unknown;
for f in *; do
[[ -f $f ]] &&
if [[ $f =~ \. ]]; then
mkdir -p "${f##*.}" &&
mv "$f" "${f##*.}"/;
else mv "$f" unknown/; fi;
done