Προς το περιεχόμενο

[INFO] Η δύναμη της Κονσόλας


Manos-Sx

Προτεινόμενες αναρτήσεις

>#!/bin/bash

COUNT=1234
for iL in `ls *.{jpg,JPG}`
do      
       echo "mv ${iL} IMG_${COUNT}.JPG"
       (( COUNT++ ))
done
unset COUNT

 

Μπορεί εύκολα να μετατραπεί το ls σε regular expression για να δέχεται οποιονδήποτε συνδυασμό κεφαλαίων-μικρών καθώς επίσης και να δέχεται τον αρχικό αριθμό από το input σαν παράμετρο στο script ελέγχοντας το $# και το $1. Μπορεί επίσης να βελτιωθεί ώστε να αναγνωρίζει κάποιο αρχείο αν είναι όντως jpg ή όχι με την χρήση της file.

Αν υπάρχει ενδιαφέρον το post-άρω :-)

PS: δουλεύει μόνο με bash (και zsh). Για (t)csh είναι αλλιώς η σύνταξη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 889
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Καλά NullScan αυτό το *.{jpg,JPG} ούτε που θα φανταζόμουν να το κάνω ποτέ! Επομένως γίνεται και με ls *.[jJ][pP][gG]... Thanks και για το (( COUNT++ )).

 

Η for όμως δεν έχει πρόβλημα με τα κενά στα ονόματα των αρχείων;

Νομίζω ότι πρέπει να προηγηθεί IFS=$'\n' για να χρησιμοποιεί το newline σαν διαχωριστικό αντί του κενού...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επομένως γίνεται και με ls *.[jJ][pP][gG]

Βεβαίως.

 

Thanks και για το (( COUNT++ ))

Παρακαλώ ;)

 

Η for όμως δεν έχει πρόβλημα με τα κενά στα ονόματα των αρχείων;

Νομίζω ότι πρέπει να προηγηθεί IFS=$'\n' για να χρησιμοποιεί το newline σαν διαχωριστικό αντί του κενού...

Σωστό.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 2 εβδομάδες αργότερα...

Μια ερώτηση!

έχουμε το παρακάτω:

>
#!/bin/bash
#tsa.sh

echo enter the name
read a

#Ypotithete bazo sto "name=" pio kato to auto pou edosa sto a... 
sed 's/name=*/name=$a/g' ~/Desktop/tsa.sh | tee ~/Desktop/tsa.sh

name=
exit 0;

 

Γίνετε αυτό που πάω να κάνω?

Έτσι όπως είναι δεν γίνεται...αλλά με κάποια αλλαγή μπορεί να γίνει?

Θέλω το όμως το "name=*" της sed να μένει απείραχτο!

 

Αν λέω λαλακίες μην βαράτε, ακόμα στο δημοτικό είμαι. :-D

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Θέλω να περνάω την τιμή μιας μεταβλητή μέσα σε ένα script απο το πληκτρολόγιο χωρίς να χρησιμοποιώ βοηθητικό αρχείο.

Το κομμάτι του κώδικα που δίνω πιο πάνω θα μπεί σε ένα script το οποίο όταν το τρέχω παράδειγμα με την παράμετρο -read (tsa.sh

--read) θα εισάγω ένα κατάλογο.

Σε άλλο μέρος σου κώδικα που θα εκτελείτε με την παράμετρο --write θα εκτελείτε κάτι σαν echo $name .

Συγκεκριμένα θέλω όταν το τρέχω με την παράμετρο --read να δίνω κάποιες τιμές και βάζοντας το στον cron με παράμετρο --write να εκτελείτε άλλος κώδικας ο οποίος θα χρησιμοποιεί τις τιμές που έδωσα στην --read.

 

Λοιπόν?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δηλαδή, θες τρέχοντας το tsa.sh --read να του δίνεις κάποιες τιμές τις οποίες θα αποθηκεύει στο ίδιο το αρχείο; Ωστε μετά η tsa.sh --write να κάνει κάτι με την αποθηκευμένη τιμή του name;

Στο ίδιο το αρχείο δεν ξέρω αν γίνεται. Υπάρχει κάποιος ειδικός λόγος που θέλεις να μην έχεις ξεχωριστό αρχείο για τα δεδομένα σου; Θα το ψάξω πάντως να δω αν γίνεται.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μια ερώτηση!

έχουμε το παρακάτω:

>
#!/bin/bash
#tsa.sh

echo enter the name
read a

#Ypotithete bazo sto "name=" pio kato to auto pou edosa sto a... 
sed 's/name=*/name=$a/g' ~/Desktop/tsa.sh | tee ~/Desktop/tsa.sh

name=
exit 0;

 

Γίνετε αυτό που πάω να κάνω?

Γίνεται, ως εξής:

>
sed 's/^name=.*/name="'"$a"'"/' -i "$0"

Παρατήρησε τα εξής:

  • Οι μεταβλητές του shell δεν αντικαθιστώνται απ' τις τιμές τους όταν βρίσκονται μέσα σε μονά εισαγωγικά, παρά μόνο όταν είναι σκέτες ή σε διπλά εισαγωγικά.
  • Σε περίπτωση που στο $a περιμένεις να υπάρχει κενό, πρέπει να το περικλείσεις σε εισαγωγικά, αλλιώς η 2η λέξη θα σπάσει τα arguments του sed. Π.χ. δοκίμασε
    >
    a="foo bar"
    ls $a
    ls "$a"
    


    σε bash για να καταλάβεις τη διαφορά. Γενικά είναι καλό να βάζεις εισαγωγικά γύρω από οποιαδήποτε μεταβλητή θες να σημαίνει ένα μόνο πράγμα.

  • Επίσης, σε περίπτωση που στο $a περιλαμβάνεται κενό, θες τελικά η γραμμή που θα δημιουργηθεί να είναι της μορφής:
    >
    name="foo bar"
    


    Διαφορετικά, χωρίς τα διπλά εισαγωγικά, θα γκρινιάξει το shell. Επομένως δες πως έχω ενσωματώσει τα διπλά εισαγωγικά μέσα στα μονά.

  • Το carret (^) στο regular expression, το οποίο σημαίνει «αρχή γραμμής», είναι αυτό που θα σε βοηθήσει να αντικαταστήσεις μόνο τη γραμμή που θες.
  • Το * δε δουλεύει όπως στο shell, αντίθετα σημαίνει «οποιοδήποτε πλήθος από τον προηγούμενο χαρακτήρα ή την προηγούμενη ομάδα». Κοινώς, το 'name=*' κάνει match και replace το name, το name=, το name===, το name====== κ.ο.κ.. Αυτό που θές είναι name=.*, το οποίο κάνει match το string "name=<οτιδήποτε ή και τίποτα>".
  • Η πατέντα που κάνεις με το tee δε χρειάζεται, μπορείς να χρησιμοποιήσεις το -i (in-place) option του sed, το οποίο κάνει τις αντικαταστάσεις κατευθείαν μέσα στο αρχείο.
  • Ποτέ μην κάνεις hardcode το όνομα του εκτελέσιμου. Χρησιμοποίησε το $0 αντ' αυτού, ώστε το script να εξακολουθήσει να παίζει ακόμα και όταν το μετονομάσεις σε κάτι άλλο.
  • To g στο τέλος της regular expression δε χρειάζεται, αφού δεν περιμένεις να συναντήσεις περισσότερες από μια φορές το "name=<κάτι>" στην ίδια γραμμή.

Γενικά τα self-modifying shell scripts δεν είναι και πολύ καλή ιδέα. Αν θες απλά να τροποποιείς μεταβλητές, μπορείς να τις αποθηκεύεις σε ένα εξωτερικό αρχείο, το οποίο να κάνεις source. Αν θυμάμαι καλά, έχεις ubuntu, οπότε δες πως δουλεύουν τα initscripts (/etc/init.d/*), τα οποία συνήθως κάνουν source κάτι από το /etc/default/.

 

edit: Advanced Bash Scripting. Καλή ανάγνωση ;-)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ευχαριστώ πολύ τις κινητές βιβλιοθήκες πανεπιστημιακού τουλάχιστον επιπέδου. :-D

Καταπληκτικότατοι!!!

Αναρωτιέμαι αν ποτέ κολλήσατε σε κάποιο σημείο γράφοντας script!

Βγάζω το καπέλο για ακόμη μια φορά... :-)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αναρωτιέμαι αν ποτέ κολλήσατε σε κάποιο σημείο γράφοντας script!

Βγάζω το καπέλο για ακόμη μια φορά... :-)

Ελπίζω ο πληθυντικός να μην είναι για μένα :P

 

Πάντα υπάρχει κάτι που μπορεί να χρειαστεί να κάνεις και να κολλήσεις, είναι απόλυτα φυσιολογικό, όσο κώδικα και να έχεις γράψει. Επίσης, συνήθως τίποτα δε μου παίζει με την πρώτη. Γι' αυτό όμως υπάρχουν οι manpages, οι infopages και τα HOWTOs. Το θέμα είναι να ξέρεις 5 βασικές έννοιες, να ξέρεις που να ψάξεις και να ξέρεις να ερμηνεύεις τα σφάλματα που εμφανίζονται στην οθόνη σου.

 

Μια καλή αρχή πάντως είναι να ψάξεις τα initscripts της διανομής σου, γιατί συνήθως είναι πολύ καλής ποιότητας και κατάλληλα για να δεις μερικούς γενικούς μηχανισμούς που χρησιμοποιούνται.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

O πληθυντικός δεν πήγαινε μόνο σε εσάς κύριε καθηγητά , αλλά και στους υπόλοιπους κυρίους καθηγητές του μεγαλύτερου και ποιοτικότερου διαδικτυακού *nix σχολείου. :-D

 

@apoikos το ποστ σου έχει γίνει ήδη bookmark!

Το ξέρω οτι και την επόμενη φορά το ίδιο κόλλημα θα έχω...θέλω αρκετή εξάσκηση, εκτός απο διάβασμα ακόμα . :o

 

Αυτή η καταραμένη sed και τα "''''"' δυο χρόνια με κυνηγάνε :lol:

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άλλη μια απορία...

έχουμε και λέμε...

εκτελώντας την εντολή παίρνω:

>:~$ sudo crontab -l
# router auto reboot
5,15,25,35,45,55 * * * *        /usr/bin/routerreboot.sh
# This file was written by KCron. Copyright (c) 1999, Gary Meyer
# Although KCron supports most crontab formats, use care when editing.
# Note: Lines beginning with "#\" indicates a disabled task.

 

Ωραία ως εδώ...

(τα παρακάτω είναι υποθετικά, δεν τα δοκίμασα μην κάνω βλακεία)

 

Τώρα θέλω να προσθέσω κάτι ακόμα...

έχω το αρχείο tsa.txt το οποίο έχει μέσα την γραμμή:

>5,15,25,35,45,55 * * * *        /usr/bin/lalalala.sh

 

Αν εκτελέσω την εντολή:

1)sudo crontab tsa.txt

και μετά:

sudo crontab -l

θα πάρω το αποτέλεσμα:

>:~$ sudo crontab -l
# router auto reboot
5,15,25,35,45,55 * * * *        /usr/bin/routerreboot.sh
# This file was written by KCron. Copyright (c) 1999, Gary Meyer
# Although KCron supports most crontab formats, use care when editing.
# Note: Lines beginning with "#\" indicates a disabled task.
5,15,25,35,45,55 * * * *        /usr/bin/lalalala.sh

 

????

Αν όχι τι πρέπει να έχει μέσα το tsa.txt? ή πιο θα είναι το αποτέλεσμα?

 

2)Αν εκτελέσω την εντολή:

sudo crontab -r

Θα αδειάσει όλο το αρχείο, θα διαγραφεί, τι?

Πως θα γίνει να διαγράψω μόνο το δεύτερο job (5,15,25,35,45,55 * * * * /usr/bin/lalalala.sh) αφήνοντας απείραχτα τα υπόλοιπα.

 

Νομίζω μπορώ με sudo crontab -e και διαγραφή με το χέρι...

...αυτόματα μέσω εντολής όμως μπορώ?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άλλη μια απορία...

έχουμε και λέμε...

εκτελώντας την εντολή παίρνω:

>:~$ sudo crontab -l
# router auto reboot
5,15,25,35,45,55 * * * *        /usr/bin/routerreboot.sh
# This file was written by KCron. Copyright (c) 1999, Gary Meyer
# Although KCron supports most crontab formats, use care when editing.
# Note: Lines beginning with "#\" indicates a disabled task.

 

Ωραία ως εδώ...

(τα παρακάτω είναι υποθετικά, δεν τα δοκίμασα μην κάνω βλακεία)

Αν θες απλά να τρέχει κάτι κάθε 10 λεπτά, μπορείς να γράψεις */10 αντί για 5,15,25 κλπ

 

Τώρα θέλω να προσθέσω κάτι ακόμα...

έχω το αρχείο tsa.txt το οποίο έχει μέσα την γραμμή:

>5,15,25,35,45,55 * * * *        /usr/bin/lalalala.sh

 

Αν εκτελέσω την εντολή:

1)sudo crontab tsa.txt

και μετά:

sudo crontab -l

θα πάρω το αποτέλεσμα:

>:~$ sudo crontab -l
# router auto reboot
5,15,25,35,45,55 * * * *        /usr/bin/routerreboot.sh
# This file was written by KCron. Copyright (c) 1999, Gary Meyer
# Although KCron supports most crontab formats, use care when editing.
# Note: Lines beginning with "#\" indicates a disabled task.
5,15,25,35,45,55 * * * *        /usr/bin/lalalala.sh

 

????

Αν όχι τι πρέπει να έχει μέσα το tsa.txt? ή πιο θα είναι το αποτέλεσμα?

Όχι, το crontab που έχει ο χρήστης ειναι ένα και (τουλάχιστον στο vixie-cron), κάθε κλήση της crontab το αντικαθιστά. Αν θες να προσθέσεις κάτι στο τέλος του crontab, τότε μπορείς να χρησιμοποιήσεις το εξής κομψό:

>
cat <(crontab -l) kot.cron | crontab -

Το <(εντολή) σημαίνει "αντί για αρχείο, πέρνα το output της εντολής ως είσοδο"

 

2)Αν εκτελέσω την εντολή:

sudo crontab -r

Θα αδειάσει όλο το αρχείο, θα διαγραφεί, τι?

Πως θα γίνει να διαγράψω μόνο το δεύτερο job (5,15,25,35,45,55 * * * * /usr/bin/lalalala.sh) αφήνοντας απείραχτα τα υπόλοιπα.

 

Νομίζω μπορώ με sudo crontab -e και διαγραφή με το χέρι...

...αυτόματα μέσω εντολής όμως μπορώ?

Ναι, αδειάζει όλο το crontab. Στα πλαίσια λοιπόν της προηγούμενης εντολής, μπορείς απλά να:

>
crontab -l | sed 'σβήσε_ό,τι_θες' | crontab -

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...