Bash scripts & χαρακτήρες newline
Δημοσιεύτηκε: Πέμ Δεκ 27, 2007 2:57 am
Προσπαθώ το τελευταίο δίωρο (μάλλον) να κάνω μια αρκετά απλή δουλειά μέσω ενός bash script. Μέρος της δουλειάς αυτής απαιτεί η έξοδος ενός προγράμματος (η οποία περιέχει τυχαίο αριθμό γραμμών με περιεχόμενα που δεν έχουν σημασία για τη συζήτηση) να "καθαριστεί" από whitespace (δηλ. πολλαπλά spaces, tabs, newlines, κλπ).
Με ένα απλό sed script μπόρεσα να καθαρίσω τα πάντα, εκτός φυσικά από το newline. Παραθέτω ένα παράδειγμα που δεν δουλεύει για να μην μπείτε στο ίδιο τριπάκι. Μπορείτε να τρέξετε την εντολή σε οποιονδήποτε κατάλογο έχει πάνω από ένα αρχείο (αλλιώς δεν θα έχετε newlines
):
Το παραπάνω θα έπρεπε να παίρνει τη λίστα των αρχείων το ένα κάτω από το άλλο (αυτό κάνει η εντολή ls -1) και κατόπιν να αντικαθιστά τον χαρακτήρα αλλαγής γραμμής (newline ή \n) με την έκφραση "no new line". Δεδομένου, όμως, ότι το sed "επεξεργάζεται" το περιεχόμενο που του πλασάρετε γραμμή-προς-γραμμή, δεν πρόκειται ποτέ να βρείτε newline για να αντικαταστήσετε.
Σε όλη αυτή τη διαδικασία βρήκα και κάτι άλλο αξιοπερίεργο που με καθυστέρησε αρκετά από το να βρω τη λύση και αφορά την εντολή echo. Εφ' όσον το παραπάνω sed script δεν έχει αποτέλεσμα, ας κρατήσουμε μόνο την εντολή ls -1. Ουσιαστικά εγώ δούλεψα με μεταβλητές τις οποίες μετά έκανα echo, αλλά το ίδιο γίνεται και χωρίς την διαμεσολάβησή τους. Εκτελέστε την παρακάτω εντολή:
Θα εμφανιστεί στην οθόνη σας η λίστα με τα αρχεία το ένα κάτω από το άλλο. Σαν να είχατε γράψει απλώς ls -1. Τρέξτε τώρα την παραπάνω εντολή χωρίς τα εισαγωγικά:
Θα εμφανιστεί η λίστα με τα ίδια αρχεία, μόνο που δεν θα βρίσκονται το ένα κάτω από το άλλο αλλά το ένα δίπλα στο άλλο. Εννοείται, φυσικά, πως αν είχατε αποθηκεύσει τα παραπάνω σε μεταβλητές και προσπαθούσατε να κάνετε επεξεργασία (π.χ. με τους τελεστές ${#}, κλπ) θα είχατε πρόβλημα, καθώς τελικά τα newlines υπάρχουν αλλά στη μια περίπτωση "κρύβονται". Αν κάποιος γνωρίζει γιατί μπορεί να συμβαίνει αυτό (δηλ. αν φταίει το bash ή η echo) θα με ενδιέφερε πάρα πολύ.
Το αίσιο αποτέλεσμα της όλης ιστορίας (γιατί ήθελα να απαλείψω τα newlines) είναι τελικά πιο απλό απ' ό,τι περίμενα: Η εντολή tr, η οποία μπορεί να αφαιρέσει ή να αντικαταστήσει χαρακτήρες στο σύνολο των δεδομένων που το ταΐζετε (όπως υποθέτω με κάποιον τρόπο θα μπορεί να κάνει και το sed αν μπορεί κανείς να το βγάλει από το line-by-line mode). Η σωστή, λοιπόν, (είτε σε εμφάνιση στην οθόνη είτε σε αποθήκευση δεδομένων) γραφή είναι η παρακάτω:
Εύχομαι να μην παιδευτεί ποτέ κανείς ξανά με αυτό το πράγμα... δεν αξίζει 
Με ένα απλό sed script μπόρεσα να καθαρίσω τα πάντα, εκτός φυσικά από το newline. Παραθέτω ένα παράδειγμα που δεν δουλεύει για να μην μπείτε στο ίδιο τριπάκι. Μπορείτε να τρέξετε την εντολή σε οποιονδήποτε κατάλογο έχει πάνω από ένα αρχείο (αλλιώς δεν θα έχετε newlines
Κώδικας: Επιλογή όλων
ls -1 | sed -e "s/\n/no new line/"Σε όλη αυτή τη διαδικασία βρήκα και κάτι άλλο αξιοπερίεργο που με καθυστέρησε αρκετά από το να βρω τη λύση και αφορά την εντολή echo. Εφ' όσον το παραπάνω sed script δεν έχει αποτέλεσμα, ας κρατήσουμε μόνο την εντολή ls -1. Ουσιαστικά εγώ δούλεψα με μεταβλητές τις οποίες μετά έκανα echo, αλλά το ίδιο γίνεται και χωρίς την διαμεσολάβησή τους. Εκτελέστε την παρακάτω εντολή:
Κώδικας: Επιλογή όλων
echo "$(ls -1)"Κώδικας: Επιλογή όλων
echo $(ls -1)Το αίσιο αποτέλεσμα της όλης ιστορίας (γιατί ήθελα να απαλείψω τα newlines) είναι τελικά πιο απλό απ' ό,τι περίμενα: Η εντολή tr, η οποία μπορεί να αφαιρέσει ή να αντικαταστήσει χαρακτήρες στο σύνολο των δεδομένων που το ταΐζετε (όπως υποθέτω με κάποιον τρόπο θα μπορεί να κάνει και το sed αν μπορεί κανείς να το βγάλει από το line-by-line mode). Η σωστή, λοιπόν, (είτε σε εμφάνιση στην οθόνη είτε σε αποθήκευση δεδομένων) γραφή είναι η παρακάτω:
Κώδικας: Επιλογή όλων
ls -1 | tr "\n" " "