find + grep για απαιτητικούς...τεμπέληδες

Panos Prokopiou pprok at bistromathics.org
Wed Dec 6 10:53:51 EET 2006


On Tuesday 05 December 2006 22:15, Giorgos Keramidas wrote:
> On 2006-12-05 21:41, Nick Demou <ndemou at gmail.com> wrote:
> > μια φορά το μήνα τουλάχιστον θα χρειαστεί να κάνω μια αναζήτηση
> > "προχωρημένη" για τις ταπεινές μου γνώσεις bash. Π.χ.:
> >
> > ψάχνω για αρχεία των τελευταίων 7 ημερών που
> >    ΚΑΙ έχουν στις πρώτες 50 γραμμές την λέξη "ΧΧΧ"
> >    ΚΑΙ έχουν οπουδήποτε την λέξη "free"
> > (οι λέξεις στην τύχη :-)
> >
> > εν τέλη με ένα συνδιασμό find -exec, κάποιου πρόχειρου Script και αν
> > είμαι άτυχος και κανενός temp αρχείου πάντα κάνω την δουλειά μου αλλά
> > το όλο εγχείρημα μου πέρνει αρκετή ώρα (είμαι ξεχασιάρης γέρος και
> > ανοίγω την man page του find και του grep και το bash scripting how-to
> > κάθε μα κάθε φορά*)
> >
> > γνωρίζει κανείς κάποια console based* εναλακτική πρόταση ή ΠΡΕΠΕΙ να
> > μάθω απ'έξω κι ανακατοτά το shell?
>
> Πρέπει να μάθεις απέξω κι ανακατωτά το shell:
>
>     find somepath/ -mtime 7d -or -mtime 6d -or -mtime 5d \
>         -or -mtime 4d ... | \
>     while read file ; do
>         xxxflag=$(head -50 "${file}" | grep -q "XXX")
>         freeflag=$(grep "free" "${file}")
>         if test ${xxxflag} -eq 0 && test ${freeflag} -eq 0 ; then
> 	    echo "${file}"
> 	fi
>     done
>
> Η `γλώσσα' του shell έχει γραφτεί για να μπορεί κανείς να συνδυάσει, με
> σχετικά εύκολο[1] τρόπο, πολλές εντολές και να βγάλει τερατουργήματα
> όπως το παραπάνω σε μισό λεπτό.
>
> [1] Εντάξει, το "εύκολο" ήταν λίγο υπερβολικό :)

Εχθές διαπίστωσα πως το σύστημά μου είχε μολυνθεί με πακέτα από το unstable 
branch του debian. Να πως τα έβγαλα :-) (σχεδόν δλδ γιατί χρειάστηκε να βάλω 
και χέρι)

env COLUMNS=200 dpkg -l | grep ^ii | awk '{print $2}' | \
 xargs env COLUMNS=2000 apt-cache madison | awk '{ print $1 " " $3 " " $6}'> \
   install_packages-available_versions.txt && \
env COLUMNS=2000 dpkg -l | grep ^ii | awk '{system("apt-cache madison " $2 "\|
  grep " $3)}' | awk '{print $1 " " $3 " " $6}' > \
   install_packages-installed_versions.txt && \
cat install_packages-installed_versions.txt | awk '{ print $1 " " $2}' | \  
 uniq -c | awk '$1==1 {system("grep ^"$2 " \
 install_packages-installed_versions.txt")}' | grep -v etch | \ 
 awk '{system("grep ^" $1 " install_packages-available_versions.txt | \
 grep etch")}' | awk '{ print $1 "=" $2}' | \
 sudo xargs apt-get -y --force-yes install

μετά από αυτό, αν και δεν το έγραψα ως script, απλά το δούλευα μέχρι να φτάσει 
να κάνω αυτό που θέλω από την γραμμή εντολών, μπορώ να σου πω ότι ο κώδικάς 
σου δεν διαβάζεται. Ευτυχώς είσαι από αυτούς που αναφέρονται στις μεταβλητές 
με ευλάβια, "${name}".

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

Η δική μου προσέγγιση είναι αυτή
find \! -mtime +7 -type f -exec sh -c "head -n 50 '{}' | \
  grep 'XXX' >/dev/null  2>&1 && echo '{}'" ';' | \
  xargs grep -H "free" | cut -f 1 -d: | sort | uniq

χρησιμοποιώ αρκετά τα 
find -exec sh -c "cmd '{}' >/dev/null 2>&1 && echo '{}'" ';'
xargs -i%i -P1 -n1 cmd %i
sort | uniq
sed -e 's|||'
και τελευταία και την awk αντί της cut και όχι μόνο

Και κάτι ακόμα προς το Νίκο που ξεκίνησε το θέμα. Χρόνια πολλά ;-)
Και αυτό που εσύ αντιλαμβάνεσαι ως "ΚΑΙ αυτό ΚΑΙ το άλλο" στον χώρο της 
πληροφορικής λέγεται απλά ΚΑΙ δλδ "αυτό ΚΑΙ το άλλο".

και για να μην προτρέξεις το "αυτό 'Η το άλλο" σημαίνει "αυτό 'Η/ΚΑΙ το άλλο",
το "'Η αυτό 'Η το άλλο" εκφράζεται από το XOR (το προφέρουμε ξορ, τυπικά 
eXclusive OR"

τα ρέστα μου
--pprοk




More information about the Linux-greek-users mailing list