posted by qubix on April 5, 2012

Ας υποθέσουμε πως θέλετε να κάνετε upgrade ένα μέρος μόνο των εγκατεστημένων πακέτων που έχετε. Για παράδειγμα έχετε εγκαταστήσει το mate και θέλετε να το κάνετε upgrade χωρίς όμως ένα μαζικό apt-get update ή ακόμη χειρότερα apt-get dist-upgrade.

Αυτό που θέλουμε είναι
1) ποιά πακέτα του mate έχουν εγκατασταθεί?
αυτό δεν είναι και πολύ δύσκολο, το dpkg -l μπορεί να μας δείξει τι υπάρχει εγκατεστημένο και με ένα pipe σε grep να διαλέξουμε τα mate πακέτα

dpkg - l | grep mate

2)κατάλληλη μορφή της λίστας με τα εγκατεστημένα πακέτα
το πρόβλημα είναι πως θα έχουμε τα αποτελέσματα σε μια μορφή που δεν είναι χρήσιμη για να την περάσουμε στο apt

ii  libmate      1.2.0-2~wheezy    MATE library
ii  libmate-common  1.2.0-2~wheezy    MATE library (common files)
ii  libmatecanvas   1.2.0-1  powerful object-oriented display engine


τη λύση δίνει η γνωστή-άγνωστη AWK η οποία μπορεί να πάρει input μια συμβολοσειρά και να τη χωρίσει σε πεδία, από τα οποία εμείς θα της πούμε τι να δείξει

awk '{print $2}'

στην περίπτωση του output μας από το dpkg, το $1 αντιστοιχεί στο "ii", το $2 στο εκάστοτε όνομα του πακέτου, το $3 στην έκδοση κ.ο.κ

αν τώρα κάνουμε pipe το ouput του dpkg και της grep στην AWK, θα έχουμε:

dpkg -l | grep mate | awk '{print $2}'

το οποίο δίνει

libmate
libmate-common
libmatecanvas


πολύ καλύτερα αλλά μπορεί να βελτιωθεί κιάλλο!
Από το manual της AWK βλέπουμε πως μπορούμε να αλλάξουμε την εξορισμού "ανά σειρά" απάντηση στο input που της δίνουμε σε ότι θέλουμε, οπότε στην περίπτωσή μας βολεύει το κενό (space)->

awk 'BEGIN {ORS = " "} ; { print $2 }'

όπου ORS = το πως θα ενώσει τις απαντήσεις στο output η AWK

οπότε τώρα η one-liner εντολή μας γίνεται:

dpkg -l | grep mate | awk 'BEGIN {ORS = " " } ; { print $2 }'

το output της οποίας πλέον είναι:

libmate-common mate-applets mate-applets-common ...κοκ


3)apt-get install
Άρα τώρα μπορούμε να χρησιμοποιήσουμε την παραπάνω one-liner σε συνδυασμό με το apt ως εξής:

apt-get install `dpkg -l | grep mate- | awk 'BEGIN {ORS = " " } ; { print $2 }'`

προσέξτε πως έβαλα την one-liner μέσα σε δύο " ` ", αυτό ισοδυναμεί με το output της one-liner δλδ πρώτα θα εκτελεστεί ότι έχουμε στα "`" και μετά θα περαστεί στο apt!

Μετά αρκεί να πατήσουμε ένα "y" και enter :]

hyperworks