Toon posts:

[bash] find in for-loop

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben een bash script (draaiend onder FreeBSD) in elkaar aan het zetten om m'n clients te backuppen. Hiervoor wordt deze for-loop gebruikt:

code:
1
2
3
4
        for j in `find $tempdir/ \! \( -name "*.dat" -size +10000000c \) -size -100000000c`
        do
            cp -Rpv $j $backupdir/$i
        done


korte uitleg:
De Dschijf van de client is gemount naar $tempdir. Hier worden alle .dat bestanden kleiner dan 10MB, en alle overige bestanden kleiner dan 100MB gekopieerd naar de backup-dir op de server. Er is alleen 1 situatie waarin dit misloopt, en ik heb geen idee hoe ik dat moet oplossen.

probleem:

stel dat "d:/documents/bastandsnaam met spatie.doc" gevonden wordt door de find, dan ziet de for-loop dit als drie losse bestanden.

Er zal dus geprobeerd worden om
* d:/documents/bastandsnaam
* met
* spaties.doc

te kopieren. Alle drie bestaan uiteraard niet, en het originele bestand wordt niet gekopieerd.

Nu is alleen nog de vraag hoe ik dit kan voorkomen. Zo dacht ik bijvoorbeeld aan een manier om de spaties tijdelijk door _ te vervangen oid, maar dan zou ik wederom een for-loop nodig hebben, en daar gaat het nou net mis. Ik zit dus een beetje in een cirkel-redenering waar ik niet meer uitkom :'(

  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

code:
1
cp -Rpv "$j" $backupdir/$i
toevallig?

Nog eens lezen: het zal wel niet :)

[ Voor 41% gewijzigd door Rataplan op 22-05-2003 10:49 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • gjkamstra
  • Registratie: September 2000
  • Laatst online: 20:43
GIng dit niet met xargs?

Hier had een grappige signature moeten staan, maar helaas: geen inspiratie


  • RAMeijer
  • Registratie: Februari 2000
  • Laatst online: 10-02 13:39
Zo misschien?

code:
1
2
3
4
for j in `find $tempdir/ \! \( -name "*.dat" -size +10000000c \) -size -100000000c`
        do
            cp -Rpv "$j" $backupdir/
        done

Verwijderd

Topicstarter
Rataplan schreef op 22 May 2003 @ 10:48:
code:
1
cp -Rpv "$j" $backupdir/$i
toevallig?

Nog eens lezen: het zal wel niet :)
heb ik ook geprobeerd, maar dat zet geen zoden aan de dijk

Verwijderd

code:
1
2
3
4
for line in $(find args | sed -e "s/\ /_/g"); do
  origline=$(echo ${line} | sed -e "s/_/\ /g"
  echo "origline=${origline}"
done

  • bkor
  • Registratie: November 2000
  • Niet online
Misschien aan te raden om een -type f bij find en die -R weg bij cp.. anders zal cp toch nog meer kopieëren dan je denkt.

Dit is een snelle oplossing:
code:
1
2
3
4
5
6
IFS="
"
for j in `find "$tempdir/" \! \( -name "*.dat" -size +10000000c \) -size -100000000c`
do
  cp -Rpv "$j" "$backupdir/$i"
done


Deze start cp niet op voor elk bestand:
code:
1
2
find "$tempdir/" \! \( -name "*.dat" -size +10000000c \) -size -100000000c -print0 | \
xargs -0 cp -Rpv --target-directory="$backupdir/$i"


Deze zou zelfs moeten werken als iemand 0x0 in de bestandsnaam gebruikt:
code:
1
2
find "$tempdir/" \! \( -name "*.dat" -size +10000000c \) -size -100000000c \
-exec cp -Rpv {} "$backupdir/$i" \;

Verwijderd

Topicstarter
Thanx.

[quote]
[code]
for line in $(find args | sed -e "s/\ /_/g"); do origline=$(echo ${line} | sed -e "s/_/\ /g" echo "origline=${origline}"done
Deze werkt, maar is een stuk minder snel dan deze optie:
Deze zou zelfs moeten werken als iemand 0x0 in de bestandsnaam gebruikt:
code:
1
2
find "$tempdir/" \! \( -name "*.dat" -size +10000000c \) -size -100000000c \
-exec cp -Rpv {} "$backupdir/$i" \;
Volgens mij is de -R optie wel van belang, indien deze wordt weggelaten worden alle bestanden in $backup/$i opgeslagen en ben ik dus de directorystructuur van het originele systeem kwijt

Verwijderd

LET OP: de $i werkt niet meer ( in "$backupdir/$i" )!!!

edit:
Opletten alexvandenzel... $i betekende iets anders

[ Voor 46% gewijzigd door Verwijderd op 22-05-2003 18:50 ]


  • Emmeau
  • Registratie: Mei 2003
  • Niet online

Emmeau

All your UNIX are belong to us

ik zou doen

find $tempdir/ \! \( -name "*.dat" -size +10000000c \) -size -100000000c` -exec cp -Rpv {} $backupdir/{} \;

If you choose to criticise you choose your enemies


Verwijderd

Iets in deze geest zou het helemaal moeten doen (wel van te voren variabelen vullen)

code:
1
2
3
4
5
6
7
8
9
for client in $CLIENTS;
do
    mount $MOUNT_OPTS //$client/d\$ $tempdir &&
    {
        mkdir -p $backupdir/$client
        find $tempdir $FIND_EXPRESSION -exec cp $CP_OPTIONS "{}" $backupdir/$client \;
        umount $tempdir
    }
done


De {} tussen de "" lost het spatieprobleem op.

De for ... in `find ...` do wat je eerst gebruikt zorgt voor een hoop extra rekentijd

  • Kees
  • Registratie: Juni 1999
  • Laatst online: 19:45

Kees

Serveradmin / BOFH / DoC
Verwijderd schreef op 22 mei 2003 @ 19:30:
Iets in deze geest zou het helemaal moeten doen (wel van te voren variabelen vullen)

code:
1
2
3
4
5
6
7
8
9
for client in $CLIENTS;
do
    mount $MOUNT_OPTS //$client/d\$ $tempdir &&
    {
        mkdir -p $backupdir/$client
        find $tempdir $FIND_EXPRESSION -exec cp $CP_OPTIONS "{}" $backupdir/$client \;
        umount $tempdir
    }
done


De {} tussen de "" lost het spatieprobleem op.

De for ... in `find ...` do wat je eerst gebruikt zorgt voor een hoop extra rekentijd
Bovendien kan de for lijst maar een beperkt aantal bestanden aan :)

"Een serveradmin, voluit een serveradministrator, is dan weer een slavenbeheerder oftewel een slavendrijver" - Rataplan


Verwijderd

Topicstarter
Emmeau schreef op 22 May 2003 @ 18:51:
ik zou doen

find $tempdir/ \! \( -name "*.dat" -size +10000000c \) -size -100000000c` -exec cp -Rpv {} $backupdir/{} \;
Deze variant zal niet werken.

cp -Rpv /directory/subdirectory/bastand /backupdir/directory/subdirectory/bestand

gaat niet goed indien directory en/of subdirectory in /backupdir niet bestaan

edit:

maar als ik het op deze manier doe gaat het volgens mij helemaal goed.

code:
1
2
        find . -type d \-exec mkdir -p "$backupdir/$client/"{} \;
        find . -type f \! \( -name "*.dat" -size +1000000c \) -size -10000000c \-exec cp -pv {} "$backupdir/$client/"{} \;

[ Voor 27% gewijzigd door Verwijderd op 23-05-2003 09:24 ]


Verwijderd

Je zou een shellscriptje kunnen maken (of een sh functie):
code:
1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

kopieer()
{
    mkdir -p "$backupdir/$client/`dirname "$1"`"
    cp -pv "$1" "$backupdir/$client/`dirname "$1"`"
}

expression='! ( -name "*.dat" -size +1000000c ) -size -10000000c'

find . -type f $expression -exec kopieer "{}" \;
of zo

Zomaar, uit m'n hoofd, ongetest, woei :)
Pagina: 1