giovedì 31 gennaio 2013

Troppi file con poche risorse

Qualche giorno fa ero collegato ad un server povero di risorse (povero è un eufemismo) ed avevo necessità di spostare circa 106 file da una directory. Quando si tratta di un numero elevato di file un semplice "mv *" non si può fare poiché "*" non è espanso (tipicamente Argument list too long). Non era possibile spostare l'intera directory per un vincolo che non descrivo poiché mi porterebbe fuori tema.
Ho salvato la sessione di comandi, potrebbe essere istruttiva

# ls -l | wc -l
ls: memory exhausted

# find ./ -type f -exec mv {} ../../../da_cancellare/.n_returned/ \;
find: cannot fork: Cannot allocate memory

# for i in `ls`;do mv $i ../../../da_cancellare/.n_returned/${i}; done
-bash: fork: Cannot allocate memory

# /bin/ls | tr '\n' '\0' | xargs -0 -i% mv % ../../../da_cancellare/.n_returned/

5 commenti:

  1. 10 alla 6 files??!!! WOW! E spostarne un po' alla volta per esempio cominciando da quelli che iniziano con un dato carattere a*, b*, c*...

    PS quale è la lunghezza di default della lista degli argomenti della linea di comando?

    RispondiElimina
  2. Credo che il problema di affrontare 10 alla 6 e (10 alla 6)/26 sarebbe pressocche' identico.
    Poi, per essere sinceri, ripetere il comando più di 5 o 6 volte mi suggerisce che è sbagliato l'approccio, alternativamente devo automatizzare!! :-)

    Sul PS non saprei risponderti. Fai qualche prova? :-)

    RispondiElimina
  3. Come si presentano i nomi dei file? sono numerici o anche alfabetici? e le estensioni?
    Un modo potrebbe essere quello di eseguire dei cicli for annidati P.E.
    prova questo:
    michele@pavilion-g6 ~$ for I in a c d ; do for J in a c d ; do ls /usr/bin/$I$J* ; done; done

    avresti anche il vantaggio di poter ordinare i file in directory. Ad esempio se mi creo preventivamente le directory:
    mkdir aa ac ad ca cc cd da dc dd (anche qui si può usare un ciclo for)

    poi posso riordinare i file con il comando:
    for I in a c d ; do for J in a c d ; do cp /usr/bin/$I$J*$I$J ; done; done

    la potenza di UNIX sta nel fatto che dei piccoli comandi come ls, mv... possono essere messi insieme con i comandi builtin di bash (usi bash vero? ;-)) per delle operazioni molto più complesse.

    RispondiElimina
  4. Abbi fiducia, questo lavoro lo fai molto elegantemente con il "find", un comando molto ma molto potente.
    Nel caso specifico "Cannot allocate memory", quindi è molto dura. Con i "for" non hai la minima speranza.
    Quello che ho utilizzato è un tip! :-)

    RispondiElimina
  5. Con find ed xargs mi ci incasino sempre;-P

    RispondiElimina