View Full Version : Copiare i file solo dell'utente o gruppo.......
stefanoxjx
16-09-2006, 11:33
Ciao a tutti, ho un problemino da risolvere e awk purtroppo non mi è venuto in aiuto :cry:
Ho una directory con 69000 file misti e dovrei riuscire a copiare in un'altra directory solo i file del gruppo users tralasciando tutti gli altri.
I file sono molti e per poterli gestire ho dovuto creare uno script con un ciclo for altrimenti qualsiasi comando si dia il sistema mi dice Lista degli argomenti troppo lunga.
Ho provato a smistare il traffico con awk , però sembra che l'output di ls -l non sia compatibile con questo comando.
:help:
Grazie.
Ciao.
Scoperchiatore
16-09-2006, 12:06
awk bisogna conoscerlo, ma è spaventoso :D
comunque, nel tuo caso con
ls -lah | awk '$4~/root/'
drwxr-xr-x 4 root root 4,0K 10 set 13:07 ..
-rw-r--r-- 1 root root 231 25 apr 08:56 .asoundrc
-rw-r--r-- 1 root root 42K 30 apr 10:46 .config
risolvi.
$3 è il campo dell'utente
$4 è il campo del gruppo
$9 è il file.
Quindi, se ad esempio voglio copiare tutti i file di root presenti nella mia home in /root, faccio così:
cp `ls -lah | awk '$4~/root/ {print $9}' | tr "\n" " "` /root
il tr l'ho aggiunto per sicurezza, dato che mi pare che cp non accetti "\n" come separatori di argomenti, ma non ne sono sicurissimo. Comunque, così funziona.
Scoperchiatore
16-09-2006, 12:09
Ciao a tutti, ho un problemino da risolvere e awk
I file sono molti e per poterli gestire ho dovuto creare uno script con un ciclo for altrimenti qualsiasi comando si dia il sistema mi dice Lista degli argomenti troppo lunga
Per evitare il problema, fai un for sul comando in backquote.
for i in `ls -lah | awk '$4~/root/ {print $9}' | tr "\n" " "`; do
cp "$i" /root;
done
stefanoxjx
16-09-2006, 13:22
In maniera un po' meno raffinata, avevo fatto una cosa simile, solo che non funziona, ma nemmeno la tua versione funziona.
Allora ho provato a lanciare il comando ls -lah | awk '$4~/root/' su una directory qualsiasi direttamente dalla riga di comando ed ho scoperto che sulla gentoo funziona, mentre sulla debian testing dove ho la directory con i file da elaborare non funziona :mbe:
Sulla debian, una volta lanciato il comando mi da una serie di righe vuote e basta; praticamente vedo il prompt che scappa via come se qualcuno stesse pigiando il tasto invio e poi mi ritorna il prompt. :confused:
Scoperchiatore
16-09-2006, 21:27
Si, credo che sia la versione di awk.
Devi aggiungere un'azione al pattern matching.
ls -lah | $4~/root/ awk {print $0}
dovrebbe andare.
Al posto di $0 (tutta la linea) puoi printare $3 (utente) $4 (gruppo) $9 (filename) e anche gli altri, ovviamente.
Per capire chi è $x basta che vedi l'output di quello che passi a awk. Lui divide tutto per caratteri "bianchi": quindi in
Claudio 23 Roma
Claudia 25 Firenze
Andrea 55 Modica
$1 è il nome
$2 è l'età
$3 è la città
Se mando un file con quella roba in awk '{print $3}' stampa solo la città ma di tutti
Se mando lo stesso file in awk '$1~/Claud/ {print $3}' stampa solo la città e solo di quelli che hanno il campo $1 (nome) che matcha con "Claud" e qualunque cosa prima o dopo.
Puoi anche modificare il separatore con cui awk processa il file, ma credo non ti serva.
In alternativa puoi usare find in questo modo:
find . -type f -group user -exec cp {} /destinazione \;
ciao ;)
stefanoxjx
16-09-2006, 22:16
Si, credo che sia la versione di awk.
Devi aggiungere un'azione al pattern matching.
ls -lah | $4~/root/ awk {print $0}
dovrebbe andare.
Al posto di $0 (tutta la linea) puoi printare $3 (utente) $4 (gruppo) $9 (filename) e anche gli altri, ovviamente.
Per capire chi è $x basta che vedi l'output di quello che passi a awk. Lui divide tutto per caratteri "bianchi": quindi in
Claudio 23 Roma
Claudia 25 Firenze
Andrea 55 Modica
$1 è il nome
$2 è l'età
$3 è la città
Se mando un file con quella roba in awk '{print $3}' stampa solo la città ma di tutti
Se mando lo stesso file in awk '$1~/Claud/ {print $3}' stampa solo la città e solo di quelli che hanno il campo $1 (nome) che matcha con "Claud" e qualunque cosa prima o dopo.
Puoi anche modificare il separatore con cui awk processa il file, ma credo non ti serva.
OK, ho risolto spostandomi il disco interessato sulla macchina con gentoo.
Ora, visto che ti vedo esperto di awk, volevo farti un'altra domanda, solo per curiosità perchè alla fine ho risolto lo stesso ma prendendo un giro più largo :(
Allora, con il primo script che mi hai consigliato ho estrapolato dai 69000 file tutti quelli che facevano parte del gruppo "users" e sono arrivato ad un totale di 22.093 file.
A questo punto avevo la necessità di fare un'ulteriore sgrezzatura di quei 22.093 file estraendo solo tutti i file di agosto e settembre.
Ho provato modificando lo script in questo modo:
for i in 'ls -lah | awk '$7=="set" {print $9}' | tr "\n" " "`; do
cp -Rpv /dati/salva/$i /dati/settembre;
done
Riusciresti a spiegarmi come mai questo script non ha funzionato visto che sulla cartella /dati/settembre mi sono trovato file di diversi mesi oltre a quelli di settembre.
Però se sostituisco la riga cp -Rpv /dati/salva/$i /dati/settembre; con un semplice echo $i vedo (giustamente) a video solo la lista dei file di settembre?
Spero di essermi spiegato :D
Scusa se non sono molto chiaro, ma devo scappare a letto, ho le palpebre molto pesanti :coffee:
Grazie.
stefanoxjx
16-09-2006, 22:21
In alternativa puoi usare find in questo modo:
find . -type f -group user -exec cp {} /destinazione \;
ciao ;)
Grazie Vicius, molto interessante anche questa formula.
La devo provare :)
Scoperchiatore
17-09-2006, 00:08
In alternativa puoi usare find in questo modo:
find . -type f -group user -exec cp {} /destinazione \;
ciao ;)
Io il find non l'ho mai capito :D
Scoperchiatore
17-09-2006, 00:13
OK, ho risolto spostandomi il disco interessato sulla macchina con gentoo.
Ora, visto che ti vedo esperto di awk, volevo farti un'altra domanda, solo per curiosità perchè alla fine ho risolto lo stesso ma prendendo un giro più largo :(
Allora, con il primo script che mi hai consigliato ho estrapolato dai 69000 file tutti quelli che facevano parte del gruppo "users" e sono arrivato ad un totale di 22.093 file.
A questo punto avevo la necessità di fare un'ulteriore sgrezzatura di quei 22.093 file estraendo solo tutti i file di agosto e settembre.
Ho provato modificando lo script in questo modo:
for i in 'ls -lah | awk '$7=="set" {print $9}' | tr "\n" " "`; do
cp -Rpv /dati/salva/$i /dati/settembre;
done
Riusciresti a spiegarmi come mai questo script non ha funzionato visto che sulla cartella /dati/settembre mi sono trovato file di diversi mesi oltre a quelli di settembre.
Però se sostituisco la riga cp -Rpv /dati/salva/$i /dati/settembre; con un semplice echo $i vedo (giustamente) a video solo la lista dei file di settembre?
Spero di essermi spiegato :D
Scusa se non sono molto chiaro, ma devo scappare a letto, ho le palpebre molto pesanti :coffee:
Grazie.
Io sono tornato ora dall'uscita :D
Il == è una cosa da linguaggio di programmazione e vuol dire "esattamente uguale". awk ha un pattern matching potentissimo ma con le espressioni regolari (un'espressione regolare è limitata da / e /). Quindi,meglio usare l'operatore
~
che sembra più adatto alla situazione:
for i in 'ls -lah | awk '$7~/set/ {print $9}' | tr "\n" " "`; do
cp -Rpv /dati/salva/$i /dati/settembre;
done
Se non dovesse funzionare, togli totalmente il pattern matching, mettendo la condizione nell'if:
for i in 'ls -lah | awk '{ if ($7=="set") print $9}' | tr "\n" " "`; do
cp -Rpv /dati/salva/$i /dati/settembre;
done
Inoltre, escapa sempre i nomi dei files negli scripts bash, dato che se hanno spazi o caratteri speciali possono darti errore. Quindi qui ogni volta che compare $i meglio sostituirlo con "$i", in questo modo:
for i in 'ls -lah | awk '$7~/set/ {print $9}' | tr "\n" " "`; do
cp -Rpv /dati/salva/"$i" /dati/settembre;
done
Questa è una regola generalissima e importante affinchè tu faccia scripts "portatili" almeno in cartelle più variegate del normale.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.