Script para organizar a área de trabalho em pastas / diretórios por extensão

1

Gostaria de organizar os desktops executando um script que coloca todos os seus arquivos em pastas por extensão. Eu encontrei algum código através de googling e o código que encontrei cria uma pasta com o nome do arquivo e coloca o arquivo na pasta. Eu não quero uma pasta por nome de arquivo ... Eu quero uma pasta para ter todos os arquivos .txt, outro para .jpg ... etc. Eu uso o OS X.

Aqui está o que eu tenho ... qualquer direção seria ótima, obrigado!

for file in *.txt
    do
        dir="${file%.txt}"
        mkdir -- "$dir"
        mv -- "$file" "$dir"
done
    
por jshernandez8 08.01.2016 / 01:44

2 respostas

3

Se o que você quer é um diretório por tipo de arquivo, então você quer algo mais como:

mkdir txt || { echo "Can't mkdir txt" ; exit 1 ; }
for file in *.txt ; do
    mv -- "$file" txt/
done

Observe o tratamento de falhas em mkdir . Em seu código, se já houver um arquivo com o nome contido na variável $dir , seu comando mkdir --"$dir" falhará silenciosamente e, em seguida, seu mv comando irá sobrescrever esse arquivo.

Para lidar com vários arquivos nomeados arbitrariamente - todos os arquivos com extensões de três caracteres no diretório atual - e colocá-los em diretórios por extensão de arquivo, você pode usar o seguinte código (não testado):

for file in *.??? ; do
    [ -f "$file" ] || continue
    dir="$(echo "$file" | rev | cut -c-3 | rev)"
    mkdir -p "$dir" || { echo "Couldn't mkdir -p $dir; exiting" ; exit 1 ; }
    mv -- "$file" "$dir"
done

Explicação:

O padrão *.??? corresponderá a todos os arquivos e diretórios no diretório atual cujo nome termine em um período ( . ) seguido por exatamente três caracteres.

O teste [ -f "$file" ] retornará verdadeiro somente se $file for um arquivo regular (não um diretório ou outro tipo mais especializado como um dispositivo). Caso contrário, a instrução continue ignorará o restante da passagem pela for loop.

A atribuição à variável dir parece chique, mas na verdade apenas pega o conteúdo da variável $file , inverte-a, extrai os 3 primeiros caracteres (da string invertida), inverte-a novamente e atribui a variável resultar como o valor de $dir . Em outras palavras, são os três últimos caracteres do nome do arquivo.

Em seguida, mkdir -p retornará sucesso se o diretório já existir ou será criado se não existir (e retornar sucesso). Se não retornar sucesso, você não quer tentar mover arquivos para ele! Daí o tratamento de erros.

Em seguida, o comando mv é igual ao normal.

Uma nota sobre o tratamento de erros:

Você pode ver construções como esta:

mkdir -p "$dir" || echo "Failed, exiting" && exit 1

Isso é imperfeito porque o comando exit só é executado se o comando echo tiver êxito após a falha do comando mkdir . O que você deseja, em vez disso, é ter o comando exit executado independentemente de se o comando echo é bem-sucedido, supondo que mkdir falhou. É por isso que uso as chaves como acima.

    
por 08.01.2016 / 01:51
1

Se o que você quer é um diretório por tipo de arquivo, então você quer algo mais como:

for file in *.*[!.]
do
    ext=${file##*.}
    mkdir -p -- "$ext"  &&  mv -- "$file" "$ext"/
done

Ao contrário de outros sistemas operacionais, no Unix, *.* significa, nem todos os arquivos, mas todos os arquivos cujos nomes contenham pelo menos um . (ponto, a.k.a. período), omitindo assim arquivos com nomes como txt , todolist e oddball . (Para confundir as coisas, os curingas de shell excluem arquivos cujos nomes começam com um . , a menos que a opção dotglob esteja definida. *.*[!.] (ou, equivalentemente, *.*[^.] ) restringe ainda mais isso para arquivos cujos nomes contenham pelo menos um . mas não tem . como o último caractere , omitindo assim arquivos com nomes como oddball. e odd.ball. . AFAICT, esta é uma boa caracterização de arquivos cujos nomes têm uma extensão não nula.

ext=${file##*.} extrai essa extensão, excluindo tudo até e incluindo o último ponto. Se a análise acima estiver correta, isso deve ser não nulo. A opção -p faz com que mkdir não falhe se o argumento já existir (e é um diretório). Se você tiver arquivos simples com nomes como txt , pdf e jpg , e também arquivos com nomes como shopping_list.txt (que renderá ext=txt ), ou em alguns outros casos extremos (por exemplo, você não tem permissão de gravação no diretório atual, ou não há espaço no sistema de arquivos), o mkdir irá falhar e emitirá sua própria mensagem de diagnóstico. E, por causa do && (como sugerido por @Wildcard), o seguinte mv não será tentado.

O / no final do comando mv é uma rede de segurança para evitar a destruição de arquivos simples com nomes como txt , pdf e jpg .

    mv -- "$file" "$ext"/

simplesmente falhará se o nome do destino existir como um arquivo simples (ou qualquer outro tipo de arquivo que não seja um diretório).

    
por 08.01.2016 / 02:29