Cree una carpeta "Foto" dentro de todos los directorios de forma recursiva

9

Tengo un montón de carpetas y quiero recorrer todas esas carpetas y en cada carpeta crear otra carpeta llamada "Foto"

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

Quiero tener:

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

Respuestas:

8

Desde el directorio justo arriba de F1 ejecuta este script:

El propósito del script es evitar tener directorios de fotos redundantes creados bajo directorios de fotos.

Además, está diseñado para evitar ejecutarlo accidentalmente desde una ubicación incorrecta, como el directorio raíz del usuario, mientras que no vería el F1directorio y crearía por error cientos de directorios de fotos en los palacios incorrectos.

Además, tenía la intención de crear un script fácil de seguir para que el usuario pudiera personalizarlo.

#!/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 actualizado:

  • Se ha cambiado el minúsculas pen photomayúsculas.
  • Se agregó soporte para nombres de archivos no stander (con sugerencias de Terdon).
LD James
fuente
1
Definitivamente evitaría analizar ls , puede fallar de maneras inusuales. Creo que las respuestas que evitan esto son probablemente más seguras.
Arronical
3
@Arronical lsno se analiza. Son solo comentarios para el usuario ... que muestran lo que está sucediendo. Al igual que las palabras "Este es un directorio de fotos". Le permite al usuario saber por qué no está creando un directorio allí.
LD James
1
Pensé que ese podría ser el caso, ya que no podía ver nada que se hiciera con él. En ese caso, retracto mi comentario y me
inclino
find -type d F1, ¿tal vez?
Olivier Grégoire
Tenga en cuenta que esto fallará si hay un archivo (y no un directorio) llamado $i/Photo, pero el OP no ha especificado qué debe hacerse en tal caso. También fallará en el caso, ciertamente improbable, donde uno de los $is contiene una nueva línea.
terdon
24

Puede lograrlo con una sola findllamada.

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

La parte -name 'Photo' -prune -ole indica que no vuelva a los Photodirectorios existentes (y recién creados) : si el archivo (o directorio) encontrado tiene el nombre Photo, deje de procesarlo ( -prune). En el otro caso ( -o), continúe con los directorios ( -type d) y ejecute ( -exec) el comando.

Melebio
fuente
ah bueno, lo intenté de esa manera y veo en tu respuesta dónde me estaba yendo mal :)
Zanna
@Zanna -prune? :) Sí, es bastante contra-intuitivo pero vale la pena aprenderlo.
Melebius
¿Dejará de crear una carpeta 'Foto' si existe un archivo llamado 'Foto'?
Anwar
3
@Anwar La versión actual lo hará. Hay una zona gris en los requisitos. :) Puede cambiar esto especificando -type djunto con -name 'Photo'antes -prune.
Melebius
2
@Anwar A segunda vista, no tendrá sentido. No puede crear una carpeta con el mismo nombre que un archivo normal dentro de la misma carpeta. Y findcontinuará con otras carpetas (incluidas las subcarpetas de esa carpeta, si así lo solicita).
Melebius
9

Puede pasar findresultados en whilelugar de, forya que de esta manera no se romperá si los nombres de archivo tienen espacios

Primero cd al directorio F1, luego haz:

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

Si el directorio existe, mkdirsimplemente se negará a crearlo, así que no hay problema ...

Si los nombres de su directorio pueden contener nuevas líneas u otra extrañeza exótica, use esto que puede tratar con nombres arbitrarios:

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

Gracias a @terdon por la ayuda con esto :)

Zanna
fuente
Si el F1directorio de operaciones es ~user/Pictures, moverse al directorio padre y ejecutar la línea colocará un Photodirectorio en cada directorio en su espacio, que podría ser miles. Considere agregar el F1como parte de la línea de comando para evitar un error fácil de cometer. De esa manera, si se ejecuta inadvertidamente desde el lugar equivocado, no creará directorios.
LD James
ah sí, en realidad no estaba seguro de su estructura de directorios. Sugiero hacerlo desde su F1lugar, editado @LDJames
Zanna
5

Python con os.walkpuede hacerlo con bastante facilidad y en solo unas pocas líneas 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

Explicación

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

Aquí simplemente llamamos al intérprete de Python con -cbandera para especificar el comando que damos entre comillas simples. os.walk()La función nos permite recorrer recursivamente todos los subdirectorios, y para cada subdirectorio (representado por r), creamos la carpeta Imágenes a través de la os.mkdir()función. r+"/Pictures"es solo una simple manipulación de cadenas para unir una cadena de subdirectorio y una cadena "/ Pictures" para formar una ruta

Reemplace "/ Imágenes" con "/ Foto" para satisfacer sus necesidades

Sergiy Kolodyazhnyy
fuente
4

Si está usando bash, simplemente puede ejecutar:

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

La globstaropción hace **coincidir "todos los archivos y 0 o más directorios y subdirectorios". En otras palabras, coincide con todo de forma recursiva. Debido /al final, **/coincidirá con todos los directorios y subdirectorios (sin archivos). Por lo tanto, $diterará sobre todos los directorios en el directorio actual y sus subdirectorios y el Photosdirectorio se creará en cada uno de ellos.

La -pbandera de los mkdirmedios:

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

Aquí, solo lo estoy usando para suprimir mensajes de error si el directorio de destino ya existe. Elimínelo si desea ver los errores.

Tenga en cuenta que esto no podrá crear un Photosubdirectorio en un directorio de destino que contenga un archivo llamado Foto. Sin embargo, no ha especificado qué se debe hacer en esos casos y todas las demás respuestas publicadas hasta ahora también tienen esta limitación.

terdon
fuente