
Tengo una gran cantidad de archivos pequeños, f, organizados en una estructura de directorios como esta:
/A/B/C/f
Hay 11 directorios en el nivel A, cada uno con aproximadamente 100 directorios en el nivel B, cada uno con aproximadamente 30 directorios en el nivel C, cada uno con un archivo f.
¿Cómo muevo todos los archivos a un nivel superior? Por ejemplo, dado este conjunto de archivos...
/A/B/C/f1
/A/B/C/f2 /A
/B/C/f3
/A/B/C/f4
Quiero que el directorio /A/B/
contenga 4 archivos, del f1 al f4. No es necesario eliminar los directorios C.
Espero que este sea un problema resuelto, que posiblemente involucre a find
, xargs
y whatnot
. ¿Algunas ideas?
Salud,
Jaime
Respuesta1
Es bastante simple con GNU find (como se encuentra en Linux) o cualquier otro find que admita -execdir
:
find A -type f -execdir mv -i {} .. \;
Con un estándar find
:
find A -type f -exec sh -c 'mv -i "$1" "${1%/*}/.."' sh {} \;
Con zsh:
zmv -Q -o-i 'A/(**/)*/(*)(.)' 'A/$1$2'
Si la estructura de directorios siempre tiene el mismo nivel de anidamiento, no necesita ningún recorrido recursivo (pero primero elimine los directorios vacíos):
for x in */*; do; echo mv -i "$x"/*/* "$x"/..; done
Respuesta2
Para ese conjunto de archivos, esto haría:
$ cd /A/B/C/
$ mv ./* ../
Pero espero que su problema sea algo más complicado... No puedo responder a esto... No estoy muy seguro de cómo es su estructura de directorio... ¿Podría aclararlo?
Respuesta3
Mi primera suposición es
$ find A -type f -exec mv {} .. \;
Mientras no -depth
lo especifiques, debería estar bien. NO lo he probado, así que pruébalo primero antes de comprometerte con él.
Respuesta4
Si solo desea mover archivos que están en directorios hoja (es decir, no desea moverlos /A/B/file
si /A
contienen B
subdirectorios), aquí hay un par de formas de hacerlo:
Ambos requieren esto
leaf ()
{
find $1 -depth -type d | sed 'h; :b; $b; N; /^\(.*\)\/.*\n\1$/ { g; bb }; $ {x; b}; P; D'
}
shopt -s nullglob
Éste funciona:
leaf A | while read -r dir
do
for file in "$dir"/*
do
parent=${dir%/*}
if [[ -e "$parent/${file##*/}" ]]
then
echo "not moved: $file"
else
mv "$file" "$parent"
fi
done
done
Esto será más rápido, pero no le gustan los directorios fuente vacíos:
leaf A | while read -r dir
do
mv -n "${dir}"/* "${dir%/*}"
remains=$(echo "$dir"/*)
[[ -n "$remains" ]] && echo "not moved: $remains"
done