Πως βρίσκω αρχεία που έχουν δημιουργηθεί από ημερομηνία και πριν ή μετά, π.χ. για backup, διαγραφή κλπ

dimitris | Τετ, 12/04/2013 - 19:44 | 7'

Στη γραμμή εντολών του Linux, με την εντολή find μπορείς να βρεις όλα τα αρχεία που έχουν δημιουργηθεί από μια ημερομηνία και μετά ή τις τελευταίες Χ ημέρες, και να κάνεις γρήγορα τη δουλειά σου - για παράδειγμα να πάρεις ένα backup.

Για παράδειγμα, η παρακάτω εντολη ψάχνει στον τρέχοντα κατάλογο και δείχνει στη συνηθισμένη λίστα (ls) όλα τα αρχεία που έχουν δημιουργηθεί τις τελευταίες 3 ημέρες:

find .  -maxdepth 1 -type f -mtime -3 -exec ls -lt {} +

Το maxdepth 1 σημαίνει "μην πας σε υποκαταλόγους" ενώ το mtime -3 σημαίνει "όλα τα αρχεία που έχουν φτιαχτεί τις τελευταίες 3 ημέρες". Η παράμετρος exec χρησιμοποιείται για να εκτελέσουμε την εντολή ls -lt σε κάθε αρχείο που ταιριάζει (το αρχείο δίνεται ως όρισμα με τον τελεστή {}). Η παράμετρος -t στην ls εμφανίζει τη λίστα των αρχείων από το νεότερο προς το παλιότερο.

Αντίθετα, αν θέλουμε όλα τα αρχεία που είναι παλιότερα, δηλαδή εκείνα που έχουν δημιουργηθεί πριν από τις τελευταίες 3 ημέρες, αλλάζουμε το πρόσημο της mtime από αρνητικό σε θετικό:

find .  -maxdepth 1 -type f  -mtime +3 -exec ls -ld {} +

Εναλλακτικά, αν θέλουμε περισσότερη λεπτομέρεια π.χ. αν θέλουμε όλα τα αρχεία που έχουν φτιαχτεί μετά τις 00:00 της Κυριακής 2 Δεκεμβρίου 2013, είναι πιο βολική η παράμετρος -newermt

find .  -maxdepth 1 -type f -newermt "2013-12-02 00:00" -exec ls -lt {} +

Πως θα κάναμε το αντίθετο; Δηλαδή πως θα βρίσκαμε τα αρχεία που είναι παλιότερα από 2 Δεκ 2012; Με τον τελεστή -not πριν από την -newermt

find .  -type f -not -newermt "2013-12-04 00:00" -exec ls {} \;

Ωραία, βρήκαμε τα αρχεία που μας ενδιαφέρουν. Πως θα δούμε πόσα ειναι; Με τον τελεστή | "διασωληνώνουμε" το αποτέλεσμα της find σε μια άλλη εντολή, την wc:

find .  -maxdepth 1 -type f -newermt "2013-12-01 00:00" -exec ls -lt {} + | wc -l

Αφού είδαμε πόσα είναι, αν θέλαμε να διαγράψουμε όλα όσα είναι π.χ. παλιότερα πό την ημερομηνία αυτή;

find .  -type f -newermt "2013-12-01 00:00" -exec rm {} \;

Εναλλακτικά, για μεγαλύτερη ταχύτητα, μπορούμε να κάνουμε pipe στην xargs rm (που λέει: για όσα ακολουθούν τρέξε την rm):

find .  -type f -not -newermt "2013-12-04 20:00" -print | xargs rm

Backup

Και πως θα γινόταν να τα συμπιέσουμε όλα σε ένα tarball για backup; Υπάρχουν διάφοροι τρόποι, ανάλογα με το τι ακριβώς θέλουμε.

Με την παράμετρο -exec καλούμε το εργαλείο tar και του λέμε να φτιάξει ένα gzipped tarball με όνομα backup.tar.gz και περιεχόμενα κάθε αρχείο ({}) που επιστρέφει η εντολή find:

find .  -maxdepth 1 -type f  -newermt "2013-12-01 00:00" -exec tar -czvf backup.tar.gz '{}' \+

Στην παραπάνω εντολή είναι σημαντικό το +. Χωρίς αυτό το tar θα γράφει ξανά και ξανά πάνω στο backup.tar.gz χωρίς να του προσθέτει αρχεία.

Εναλλακτικά, αν τα ονόματα των αρχείων έχουν κενά και γενικά περίεργα ονόματα, είναι πιο χρήσιμη η παρακάτω εντολή όπου χρησιμοποιούμε την παράμετρο -print0 για να τυπωθούν στην οθόνη όλα τα matching filenames. Μετά όλα αυτά τα "στέλνουμε" στην εντολή tar για συμπίεση.

find .  -maxdepth 1 -type f  -newermt "2013-12-01 00:00" -print0 | tar -czvf backup.tar.gz -T - --null

Εδώ η παράμετρος -Τ λέει στο tar να πάρει τα ονόματα των αρχείων από το αρχείο που ακολουθεί. Η παύλα αμέσως μετά του λέει "διάβασε τα πάντα από την έξοδο της προηγούμενης εντολής". Το --null του λέει να θεωρεί ως τέλος του ονόματος του αρχείο το τίποτα αντί για την αλλαγή γραμμής (χρήσιμο αν τα ονόματα των αρχείων περιέχουν περίεργους χαρακτήρες, carriage returns, κλπ).

Ολες οι παραπάνω εντολές αναφέρονται στον τρέχοντα καταλογο (αυτό δηλώνεται από την τελεία . αμέσως μετά την find) και αφορούν μόνο αρχεία (αυτό δηλώνεται με την παράμετρο -type f). Αν θέλουμε μπορούμε να ψάξουμε σε οποιονδήποτε κατάλογο, π.χ. τον /usr

find /usr  -maxdepth 1 -type f  -newermt "2013-12-01 00:00" -print0 

 

Φόρουμ
Δώσε αστέρια!

MO: 3 (ψήφοι: 1)