View Full Version : [script shell Unix] Controllo con le regexp
Teo@Unix
26-03-2009, 20:40
Allora, stò provando in vari modi a controllare che un dato di input immesso dall'utente abbia una certa formattazzione.
L'utente in questione deve inserire un orario in questo formato: hh:mm:ss ore, minuti, secondi. In caso di errore lo script visualizzerà il relativo messaggio ecc..
Volevo sapere se esiste una metodologia precisa usando le espressioni regolari, stò guardando qualcosa in merito ad awk, ma credo ci sia un metodo più semplice.
Un dato d'esempio corretto potrebbe essere questo: "19:00:56" quindi il mio pattern di convalida sarà: '/^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/', certo l'utente potrebbe ancora inserire 29:10:00. Sarebbe bello prevedere anche questo livello di stupidità dell'utente in un unica espressione regolare ma per ora sono arrivato a questa...
sono in cerca di consigli, grazie mille.
gurutech
26-03-2009, 22:38
Allora, stò provando in vari modi a controllare che un dato di input immesso dall'utente abbia una certa formattazzione.
L'utente in questione deve inserire un orario in questo formato: hh:mm:ss ore, minuti, secondi. In caso di errore lo script visualizzerà il relativo messaggio ecc..
Volevo sapere se esiste una metodologia precisa usando le espressioni regolari, stò guardando qualcosa in merito ad awk, ma credo ci sia un metodo più semplice.
Un dato d'esempio corretto potrebbe essere questo: "19:00:56" quindi il mio pattern di convalida sarà: '/^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/', certo l'utente potrebbe ancora inserire 29:10:00. Sarebbe bello prevedere anche questo livello di stupidità dell'utente in un unica espressione regolare ma per ora sono arrivato a questa...
sono in cerca di consigli, grazie mille.
pattern di convalida
/^([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/
ma lo script in che linguaggio è? l'input avviene da tastiera?
Teo@Unix
27-03-2009, 07:34
è uno script bash, la pattern indicata è l'espressione regolare che rappresenta la formattazione permessa per la stringa.
L'input è dato dall'utente, da tastiera.
In pratica l'utente deve inserire un'orario nel formato indicato.
Teo@Unix
29-03-2009, 17:40
è uno script bash, la pattern indicata è l'espressione regolare che rappresenta la formattazione permessa per la stringa.
L'input è dato dall'utente, da tastiera.
In pratica l'utente deve inserire un'orario nel formato indicato.
Nessuno sa come fare? non riesco a trovare il modo per controllare la formattazione dell'input dell'utente....se non con dispendiose e lunghe operazioni.........:confused:
Gimli[2BV!2B]
29-03-2009, 18:20
Ma, hai provato quello proposto da gurutech? Colma il buco che avevi evidenziato. Hai altri errori?
Teo@Unix
29-03-2009, 20:51
Si, grazie gurutech, credo che questa vada proprio meglio, però come eseguo il test? Una cosa del genere?
if [ "$time_value" = /^([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/ ]
then
...
Così non funziona, oppure ho pensato di fare un sostituzione e controllare che l'output sia 0, in questo caso l'input sarebbe giusto...
Gimli[2BV!2B]
29-03-2009, 21:48
Così sembra funzioni, al solito non credo sia la soluzione più elegante...
if [ `echo $time_value | grep -cE ^\([0-1][0-9]\|2[0-3]\):[0-5][0-9]:[0-5][0-9]$` -eq 1 ]
then
echo "vero"
else
echo "falso"
fi
Teo@Unix
30-03-2009, 20:45
grazie ma così non funziona c'è un problema di parentesi e "|";
quest'ultimo viene visto come il passaggio di output al comando successivo, grep mi si incasina e mi segnala la mancata occorrenza di ")", difatti interpreta fino a "|" credendo che li il comando finisca.
Comunque mi è servito di ispirazione e di lezione, devo leggere meglio le pagine di manuale:doh: .....
Ho risolto sempre in maniera "roccambolesca" in questo modo:
if [ 'echo "$time" | grep -vE ^[0-1][0-9]:[0-5][0-9]:[0-5][0-9]$ | grep -vcE ^2[0-3]:[0-5][0-9]:[0-5]:[0-9]$' -eq 0 ]
then
.....
.....
funziona perfettamente....:D
Gimli[2BV!2B]
30-03-2009, 21:26
Come non funziona? :confused: I caratteri problematici che hai evidenziato li ho preceduti con l'escape, come necessario in grep -E. Funziona pure con dash.
Beh, alla fine si è risolto, anche se non son convinto che sia il meglio...
gurutech
31-03-2009, 12:23
io costringerei l'utente ad inserire solo delle cifre, e poi verificherei quanto fatto.
#!/bin/bash
KEYPRESS=n
i=0;
ORARIO=( 0 0 0 0 0 0 )
#salva la posizione del cursore
echo -n -e "\033[s"
while ( [ $i -lt 6 ] ); do {
#ripristina la posizione del cursore
echo -n -e "\033[u"
echo -n ${ORARIO[0]}${ORARIO[1]}:${ORARIO[2]}${ORARIO[3]}:${ORARIO[4]}${ORARIO[5]}
read -s -t 1 -n 1 KEYPRESS
case "$i" in
0)
if ( echo $KEYPRESS | egrep "([0-2])" 2> /dev/null &>/dev/null ); then {
ORARIO[$i]=$KEYPRESS
i=$((i+1))
}
fi
;;
1)
if ( echo $KEYPRESS | egrep "([0-9])" 2> /dev/null &>/dev/null ); then {
VALORE="${ORARIO[0]}$KEYPRESS"
if ( [ $VALORE -lt 24 ] ); then {
ORARIO[$i]=$KEYPRESS
i=$((i+1))
}
fi
}
fi
;;
2|4)
if ( echo $KEYPRESS | egrep "([0-5])" 2> /dev/null &>/dev/null ); then {
ORARIO[$i]=$KEYPRESS
i=$((i+1))
}
fi
;;
*)
if ( echo $KEYPRESS | egrep "([0-9])" 2> /dev/null &>/dev/null ); then {
ORARIO[$i]=$KEYPRESS
i=$((i+1))
}
fi
;;
esac
}
KEYPRESS=n
done
echo -n -e "\033[u"
echo -n ${ORARIO[0]}${ORARIO[1]}:${ORARIO[2]}${ORARIO[3]}:${ORARIO[4]}${ORARIO[5]}
echo ""
Teo@Unix
31-03-2009, 14:14
Bello il tuo sistema, non ho capito casa fai qui però:
echo $KEYPRESS | egrep "([0-2])" 2> /dev/null &>/dev/null )
cioè "2>/dev/null &>/dev/null" è una redirezione di stderr su /dev/null?
e poi le opzioni di read? non esiste la pagina di manuale... :(
gurutech
31-03-2009, 14:37
Bello il tuo sistema, non ho capito casa fai qui però:
cioè "2>/dev/null &>/dev/null" è una redirezione di stderr su /dev/null?
e poi le opzioni di read? non esiste la pagina di manuale... :(
ciao,
per read devi leggere la pagina di manuale di bash
while, if case e for sono tutti nella pagina man di bash.
per le condizioni scritte tra parentesi quadre, tipo
while ( [ $i -lt 6 ] )
devi leggere la pagina di manuale di test
sempre nella pagina man di bash ti puo' interessare la sezione
ARITHMETIC EVALUATION
The shell allows arithmetic expressions to be evaluated, under certain
circumstances (see the let and declare builtin commands and Arithmetic
Expansion). [...]
per quanto riguarda la redirezione a /dev/null:
grep (ed egrep) mettono sullo standard output:
eventuali errori (che butto via con 2> )
stringa trovata se c'e' una corrispondenza (che butto via con &> )
e poi ritornano come exit status vero o falso a seconda che abbia o no trovato la stringa che cercavi. A me interessava solo l'exit status, per cui ho scartato il resto.
per ultimo ti puo' essere utile la pagina man di echo. Le sequenze di ANSI Escape (quel \033[s ) le trovi qui (http://www.linuxselfhelp.com/howtos/Bash-Prompt/Bash-Prompt-HOWTO-6.html)
se hai bisogno chiedi pure
Teo@Unix
31-03-2009, 15:09
A ok, usi l'exit status per verificare....
davvero grazie per le indicazioni,:)
ciao.
Gimli[2BV!2B]
31-03-2009, 22:36
Bello! Grazie gurutech!
Ci ho giocato un po', soprattutto col cursore e sulla semplificazione della scrittura dei test.
Ho imparato varie cose utili.
#!/bin/bash
ORARIO=( 0 0 0 0 0 0 )
ReadTime()
{
i=0
echo -n -e "\033[s"
echo -n ${ORARIO[0]}${ORARIO[1]}:${ORARIO[2]}${ORARIO[3]}:${ORARIO[4]}${ORARIO[5]}
echo -n -e "\033[u"
while read -s -n 1 KEYPRESS ; do
case "$i" in
0)
if echo $KEYPRESS | egrep -q [0-2] ; then
echo -n $KEYPRESS
ORARIO[$i]=$KEYPRESS
((i++))
fi
;;
1)
if echo $KEYPRESS | egrep -q [0-9] ; then
VALORE="${ORARIO[0]}$KEYPRESS"
if [ $VALORE -lt 24 ] ; then
echo -n $KEYPRESS
echo -n -e "\033[1C"
ORARIO[$i]=$KEYPRESS
((i++))
fi
fi
;;
2|4)
if echo $KEYPRESS | egrep -q [0-5] ; then
echo -n $KEYPRESS
ORARIO[$i]=$KEYPRESS
((i++))
fi
;;
*)
if echo $KEYPRESS | egrep -q [0-9] ; then
echo -n $KEYPRESS
if [ $i -eq 3 ] ; then
echo -n -e "\033[1C"
fi
ORARIO[$i]=$KEYPRESS
((i++))
fi
;;
esac
if [ $i -eq 6 ] ; then
break
fi
done
echo
}
echo -n "Enter time: "
ReadTime
echo
HOUR="${ORARIO[0]}${ORARIO[1]}"
MINUTES="${ORARIO[2]}${ORARIO[3]}"
SECONDS="${ORARIO[4]}${ORARIO[5]}"
echo "Hour: $HOUR, minutes: $MINUTES, seconds: $SECONDS"
echo
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.