2010-01-23 6 views
9

Sto cercando di verificare se una variabile è esattamente due numeri ma non riesco a capirlo.Regex in KornShell

Come si controllano le espressioni regolari (regex) in KornShell (ksh)?

ho provato:

if [[ $month =~ "[0-9]{2}" ]] 
if [[ $month = _[0-9]{2}_ ]] 

non sono stato in grado di trovare qualsiasi documentazione su di esso.

Qualche idea?

risposta

8
case $month in 
    [0-9][0-9]) echo "ok";; 
    *) echo "no";; 
esac 

dovrebbe funzionare.

Se avete bisogno dell'immagine completa di ricerca regexp, è possibile utilizzare egrep come questo:

if echo $month | egrep -q '^[0-9]{2}$' 
then 
    echo "ok" 
else 
    echo "no" 
fi 
+0

Durante l'utilizzo di egrep funziona, è un programma esterno e volontà rallenta molto lo script. – user1683793

0

si può provare anche questo

$ month=100 
$ [[ $month == {1,2}([0-9]) ]] && echo "ok" || echo "no" 
no 
$ [[ $month == [0-9][0-9] ]] && echo "ok" || echo "no" 
no 
$ month=10 
$ [[ $month == {1,2}([0-9]) ]] && echo "ok" || echo "no" 
ok 
$ [[ $month == [0-9][0-9] ]] && echo "ok" || echo "no" 
ok 
5

Da dove vengo io, questo è più probabile che per convalidare numerico mesi:

if (($month >= 1 && $month <= 12)) 

o

[[ $month =~ ^([1-9]|1[012])$ ]] 

o per includere uno zero per mesi a una cifra:

[[ $month =~ ^(0[1-9]|1[012])$ ]] 
3

ksh non usa le espressioni regolari; usa un linguaggio più semplice, ma ancora abbastanza utile, chiamato "shell globbing patterns". Le idee chiave sono

  • classi come [0-9] o [chly] ogni carattere nella classe.
  • Il . non è un carattere speciale; corrisponde solo a ..
  • Il ? corrisponde a qualsiasi singolo carattere.
  • * corrisponde a qualsiasi sequenza di caratteri.
  • A differenza di espressioni regolari, shell pattern globbing deve corrispondere la parola intera, quindi funziona come se fosse un regexp sarebbe sempre iniziare con ^ e finiscono con $.

Gli schemi di globbing non sono potenti quanto le espressioni regolari, ma sono molto più facili da leggere e sono molto convenienti per la corrispondenza di nomi di file e parole semplici. Il costrutto case è il mio preferito per la corrispondenza, ma ce ne sono altri.

come già notato da Alok probabilmente si desidera

case $number in 
    [0-9][0-9]) success ;; 
    *) failure;; 
esac 

anche se forse si potrebbe preferire di non corrispondere a un numero a due cifre, con zero iniziale, in modo da preferire [1-9][0-9].

+2

ksh93 supporta espressioni regolari di base ed estese utilizzando l'operatore di associazione = ~ – cdarke

+1

+1 per spiegare le differenze chiave tra espressioni regolari e schemi; @cdarke: è bello saperlo, ma non riesco a farlo supportare le espressioni _interval_ come '{2}'; per esempio. '[[11 = ~ [0-9] {2}]] && echo YES' causa un errore di sintassi; '\' -escludendo le parentesi i risultati non corrispondono; mi manca qualcosa ('ksh 93u')? – mklement0

7

Ksh è sostenuto modelli estesi limitato dal ksh88, utilizzando la sintassi

special '(' pattern ')' 

.

In ksh88, i prefissi 'speciali' di carattere cambiare il numero di partite atteso:

'*' for zero or more matches 
'+' at least one match 
'@' for exactly one match 
'?' for zero or one matches 
'!' for negation 

In ksh93, questo è stato ampliato con

'{' min ',' max '}' 

di esprimere una gamma precisa:

for w in 1423 12 "" abc 23423 9 33 3 333 
do 
    [[ $w == {1,3}(\d) ]] && print $w has between 1 and three digits 
    [[ $w == {2}(\d) ]] && print $w has exactly two digits 
done 

E infine, è possibile avere un ingombro simile a perl con '~', che introduce un intero nuovo classe di estensioni, tra cui la completa espressioni regolari con:

'~ (E) (regex)'

Più esempi si possono trovare in Finnbarr P. Murphy's blog

+3

Non hai bisogno del ~ (E) se usi = ~, questo è il default – cdarke