Crie uma pasta "Foto" dentro de todos os diretórios recursivamente

9

Eu tenho várias pastas e quero passar por todas essas pastas e, em cada pasta, criar outra pasta chamada "Foto"

F1
--F11
----F111
----F112
--F12

Eu quero ter:

F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo
OOzy Pal
fonte

Respostas:

8

No diretório logo acima de F1, execute este script:

O objetivo do script é evitar que diretórios de fotos redundantes sejam criados em diretórios de fotos.

Além disso, ele foi projetado para evitar executá-lo acidentalmente em um local errado, como o diretório raiz do usuário, enquanto ele não veria o F1diretório e criaria, por engano, centenas de diretórios de fotos nos palácios errados.

Além disso, minhas intenções eram criar um script fácil de seguir para que o usuário pudesse personalizá-lo.

#!/bin/bash

while IFS= read -r -d '' i;
do
    if [[ ! -d $i/Photo ]]; then
        # Filter to skip folders named Photo
        thisfolder="$(echo $i | sed "s/.*\///")"
        if [[ ! $thisfolder == "Photo" ]]; then
            mkdir "$i/Photo"
        fi
    fi
done < <(find F1 -type d -print0)

Script atualizado:

  • Mudou o caso inferior pem photopara maiúsculas.
  • Adicionado suporte para nomes de arquivos não stander (com sugestões de Terdon).
LD James
fonte
11
Definitivamente, evito analisar ls , pois pode falhar de maneiras incomuns. Eu acho que as respostas que evitam isso provavelmente são mais seguras.
Arronical
3
@Arronical lsnão é analisado. É apenas um feedback para o usuário ... mostrando o que está acontecendo. Assim como as palavras "Este é um diretório de fotos". Está deixando o usuário saber por que não está criando um diretório lá.
LD James
11
Eu achava que poderia ser o caso, pois não conseguia ver nada sendo feito com isso. Nesse caso, eu retirar minha comentário e inclinação da :)
Arronical
find -type d F1, talvez?
Olivier Grégoire
Observe que isso falhará se houver um arquivo (e não um diretório) chamado $i/Photo, mas o OP não especificou o que deve ser feito nesse caso. Também falhará no caso, reconhecidamente improvável, em que um dos $is contenha uma nova linha.
terdon 14/09/16
24

Você pode conseguir isso usando uma única findchamada.

find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;

A parte -name 'Photo' -prune -odiz para não recorrer aos Photodiretórios existentes (e recém-criados) : Se o arquivo (ou diretório) encontrado tiver o nome Photo, pare de processá-lo ( -prune). No outro caso ( -o), continue com os diretórios ( -type d) e execute ( -exec) o comando.

Melebius
fonte
ah bom, eu tentei dessa forma e eu vejo de sua resposta onde eu estava indo errado :)
Zanna
@Zanna -prune? :) Sim, é bastante contra-intuitivo, mas vale a pena aprender.
Melebius 14/09/16
Ele irá parar de criar uma pasta 'Foto' se existir um arquivo chamado 'Foto'?
Anwar
3
@ Anwar A versão atual será. Há uma zona cinza nos requisitos. :) Você pode alterar isso especificando -type djunto com -name 'Photo'antes -prune.
Melebius 14/09/16
2
@ Anwar À segunda vista, não fará sentido. Você não pode criar uma pasta com o mesmo nome que um arquivo regular dentro da mesma pasta. E findcontinuará com outras pastas (incluindo subpastas dessa pasta, se você estiver solicitando isso).
Melebius
9

Você pode passar os findresultados para, e whilenão, forpois dessa forma não será interrompido se os nomes de arquivos tiverem espaços

Primeiro cd para o diretório F1, então faça:

find -type d | while read dir ; do mkdir "$dir"/Photo ; done

Se o diretório existir, mkdirapenas se recusará a criá-lo, então não há problema ...

Se os nomes dos diretórios puderem conter novas linhas ou outras estranhezas exóticas, use isso que pode lidar com nomes arbitrários:

find -type d -print0 | while IFS= read -r -d '' dir ; do mkdir "$dir"/Photo ; done

Obrigado a @terdon pela ajuda com isso :)

Zanna
fonte
Se o F1diretório do op estiver ~user/Pictures, mover para o diretório pai e executar a linha colocará um Photodiretório em todos os diretórios em seu espaço, que podem ser milhares. Considere adicionar o F1como parte da linha comercial para evitar um erro facilmente cometido. Dessa forma, se for inadvertidamente executado no lugar errado, não criará diretórios.
LD James
ah sim, eu realmente não tinha certeza da estrutura de diretórios deles. Eu sugiro fazê-lo a partir F1@LDJames vez, editado
Zanna
5

Python com os.walkpode fazê-lo facilmente e em apenas algumas linhas de código

$ mkdir dir_one dir_two
$ mkdir dir_two/dir_three
$ python -c 'import os;[os.mkdir(r + "/Pictures") for r,d,f in os.walk(".")]'                 
$ tree
.
├── dir_one
│   └── Pictures
├── dir_two
│   ├── dir_three
│   │   └── Pictures
│   └── Pictures
└── Pictures

Explicação

Estamos lidando com este comando: python -c 'import os; [os.mkdir (r + "/ Pictures") para r, d, f em os.walk (".")]'

Aqui, chamamos simplesmente python intérprete com -cflag para especificar o comando que fornecemos entre aspas simples. os.walk()A função nos permite percorrer recursivamente todos os subdiretórios e, para cada subdiretório (representado por r), criamos a pasta Imagens via os.mkdir()função. r+"/Pictures"é apenas uma manipulação simples de string para unir a string do subdiretório e a string "/ Pictures" para formar um caminho

Substitua "/ Pictures" por "/ Photo" para atender às suas necessidades

Sergiy Kolodyazhnyy
fonte
4

Se você estiver usando o bash, basta executar:

shopt -s globstar
for d in **/; do mkdir -p "$d"/Photo; done

A globstaropção faz a **correspondência "todos os arquivos e 0 ou mais diretórios e subdiretórios". Em outras palavras, ele corresponde a tudo recursivamente. Por causa do /no final, **/corresponderá a todos os diretórios e subdiretórios (sem arquivos). Portanto, o $diterará sobre todos os diretórios no diretório atual e seus subdiretórios e o Photosdiretório será criado em cada um deles.

A -pbandeira dos mkdirmeios:

  -p, --parents
          no error if existing, make parent directories as needed

Aqui, estou apenas usando-o para suprimir mensagens de erro se o diretório de destino já existir. Remova-o se desejar ver os erros.

Observe que isso falhará ao criar um Photosubdiretório em um diretório de destino que contenha um arquivo chamado Foto. Você não especificou o que deve ser feito nesses casos e todas as outras respostas postadas até agora também têm essa limitação.

Terdon
fonte