Newsgroup: it.comp.os.linux.iniziare
Titolo: regexp e sed: [\1] non funge

$ echo pippo|sed -n "/\(p\)i\1/p"
pippo
e questo è ok
$ echo pippo|sed -n "/\(p\)i[\1]/p"
restituisce il prompt
In questo esempio non mi funziona il back reference se lo richiamo
all'interno delle [ ]
$ info sed
`[LIST]'
     The characters `$', `*', `.', `[', and `\' are normally not
     special within LIST.
allora ho provato con
$ echo pippo|sed -n "/\(p\)i[\\1]/p"
ma non funziona ugualmente
come si usa?
Matteo
(Eppure, senza metterci le mani sul fuoco, mi sembrava che stamattina
funzionava; che cosa avrei potuto fare, da non far funzionare un sed!!!)

 come si usa?
bè le quadre si usano per dire l'insieme di caratteri che servono, es:
$ echo pippo|sed -n '/[pio]/p'
pippo
$
ovviamente la cosa si potrebbe complicare tipo
$ echo pippo|sed -n '/^[p].*[o]$/p'
pippo
$ echo pipppo|sed -n '/^[p]i.\{3\}[o]$/p'
pipppo
$ echo pipppo|sed -n '/^\(p\)[i]\{1\}\(\1\)\{3\}[o]\{1\}$/p'
pipppo
$
Buon Divertimento!
Ps. se capisci quello che ho scritto allora capirai anche come usare i 
riferimenti

 riferimenti
Si, li ho capiti tutti quelli che hai scritto, erano abbastanza chiari (dopo 
che aver ingrandito i caratteri per distinguere quali siano le parentesi 
tonde e quali le graffe :-), ma nessuno rispecchia quello che intendevo, che 
ripeto e traduco:
$ echo pippo|sed -n "/^\(p\)i[\1]/p"
'pippo' è solo un esempio; per lo più io non so a priori che parola sia, 
anche perchè la regexp sarà data in pipe ad una cat,  per cui:
individua una parola che comincia per p seguita da una i e la stessa lettera 
con cui è iniziata la parola, che ha più senso con
$ echo pippo|sed -n "/^\(.\)i[\1]/p"
individua una parola che ha una i per seconda ed ai suoi fianchi una lettera 
uguale
per queste due si può tranquillamente usare \1 anzichè [\1] (con il quale 
sembra che non funzioni)
ma quello che più serve a me è una estensione e combinazione della seguente:
individua una parola di 4 caratteri che abbia la doppia (al centro) e che 
non termini come inizia. In pratica volevo bloccare anna o inni individuando 
piuttosto anni o inni o atto,... e cercato di scrivere:
^\(.\)\([^\1])\2[^\1\2]$
quindi
inizia con una lettera qualsiasi
la seconda non dovrà essere ovviamente uguale alla prima
questa dovrà essere scritta due volte
infine l'ultima non dovrà essere uguale alle due appena scritte.
In verità ne ho bisogno di più complessi, ma sono tutti derivati di questa
Matteo 

 ...
Da quello che ho capito (leggere il tuo italiano 
è molto difficile per me), devi ripassare il 
significato delle parentesi quadre nelle 
espressioni regolari.
Esempio:
$cat disney
pippo
pluto
paperino
paperone
topolino
minnie
clarabella
orazio
gastone
qui
quo
qua
paperina
nonna papera
archimede pitagorico
paperoga
pico de' paperis
amelia
basettoni
la banda bassotti
paperoga
ciccio
cercare le parole che iniziano per `p':
grep '^p' disney
pippo
pluto
paperino
paperone
paperina
paperoga
pico de' paperis
paperoga
cercare le parole che non iniziano per `p':
$grep '^[^p]' disney
topolino
minnie
clarabella
orazio
gastone
qui
quo
qua
nonna papera
archimede pitagorico
amelia
basettoni
la banda bassotti
ciccio
cercare le parole che iniziano per `t' e per `q':
$ grep '^[tq]' disney
topolino
qui
quo
qua
cercare le parole la cui seconda lettera non è una vocale
$ grep '^.[^aeiou]' disney
pluto
clarabella
orazio
archimede pitagorico
amelia
Buona lettura

 ripeto e traduco:
<snip>
hai fatto bene a ripetere e tradurre perchè non avevo capito...
prova questo... lo so non è sed e non è nemmeno una soluzione elegante...
$ cat prova
inna
loop
issi
anna
anni
soob
prrr
cool
boom
uffu
uffi
gool
atta
atto
$ cat prova |egrep -v '^(.)(\1){2}' |egrep -v '^(.)(.){2}(\1|\2)$'
inna
loop
anni
soob
cool
boom
uffi
gool
atto
$
VinX

> $ cat prova |egrep -v '^(.)(\1){2}' |egrep -v '^(.)(.){2}(\1|\2)$'
Che sia sed grep awk perl non importa, a me interessa che sia
funzionale.
Questa soluzione però non può andar bene per il fatto che usa 2
espressioni regolari.
Il problema è:
1) io ho fatto un esempio di un insieme di parole da 4 lettere con
pochi incastri; il mio caso reale sarà di parole di tutto il
vocabolario italiano, e quindi anche quelle un po' lunghette e con
mooooolti incastri e dipendenze tra una lettera e l'altra; così
mettere 2 regexp in pipe non è più molto funzionale.
2) una volta individuato un modello valido costruirò un 'generatore'
di espressioni regolari per la situazione in esame; fortunatamente il
formato della rappresentazione delle dipendenze è ben definita e
strutturata, così dovrebbe risultare abbastanza semplice automatizzare
la creazione di tali regexp.
Cmq. un ostacolo l'ho superato (giusto un minuto prima di leggere il
tuo post) ed è quello che tentavo di rappresentare con [\1\2] che si
scrive in modo corretto (\1|\2) come hai confermato tu.
Il secondo tassello che mi manca è la 'negazione di una espressione
regolare' che tu hai fatto con l'egrep "-v" ma che io devo mettere
dentro la regexp. Qualcosa tipo
^(.)(_NOT(\1))_x$
(una qualsiasi lettera) seguita da ('non' 'la prima lettera') seguita
da una x
dopo di questo posso iniziare a creare il mio generatore
Matteo

 espressioni regolari.
ok trovata:
$ cat prova
nnnn
innn
mmmh
inno
loop
issi
anna
anni
soob
prrr
cool
boom
uffu
uffi
gool
atta
atto
iiio
iiii
$ cat prova |egrep -v '^(.)(\1()|.()){2}((\1|\2|\3)\4)'
inno
loop
anni
soob
cool
boom
uffi
gool
atto
$
ho preso spunto da qui:
$ info regex
    * If the group doesn't participate in a match, i.e., it is part of an
      alternative not taken or a repetition operator allows zero
      repetitions of it, then the back reference makes the whole match
      fail.  For example, `(one()|two())-and-(three\2|four\3)' matches
      `one-and-three' and `two-and-four', but not `one-and-four' or
      `two-and-three'.  For example, if the pattern matches `one-and-',
      then its group 2 matches the empty string and its group 3 doesn't
      participate in the match.  So, if it then matches `four', then
      when it tries to back reference group 3--which it will attempt to
      do because `\3' follows the `four'--the match will fail because
      group 3 didn't participate in the match.
VinX


Incredibile, è già la seconda volta che sto lavorando sulla soluzione
che mi stai proponendo un minuto prima di leggere il tuo post, e mi ci
sto impazzendo (mi sono fermato per pausa pranzo, poi riprendo).
Comunque non va bene perchè non posso usare switch (-v &c.) a egrep;
ho utilizzato una sintassi sullo stesso concetto di quella proposta, ma
invertita è più difficile. Voglio lavorare completamente di regular
expression, anche per semplificare il passaggio a qualsiasi altro
programma (sed awk perl php pyton vi openoffice.....).
Stavo tentando di ripiegare ora sulle classi (:digit: :alpha: ...)
visto che queste si possono inserire in un [].
Se fosse possibile definirne di personalizzate credo che potrei
svoltare.
Matteo

Eccola:
^(.)((?!\1).)\1\1((?!\2|\1).)$
Questa regexp prende "pippo" ma non prende "mamma", cioè
-1-: (.) Prendi uno qualsiasi
-2-: ((?!\1).) prendi uno qualsiasi che non sia -1-
---: \1 prendi il primo
---: \1 prendi il primo
-3-: ((?!\2|\1).) prendi uno qualsiasi che non sia -1- o -2-
Questa l'ho generata con l'aiuto di "RegexBuddy". Purtroppo per linux
non c'è la versione demo (ma per fortuna esiste wine).
http://www.topshareware.com/RegexBuddy-transfer-15609.htm
Uso anche "kregexpeditor" però questo non supporta il backreference,
se però si mettono a mano lettere per testare va bene.
dunque. non l'ho potuto provare su un file perchè non so come
inserirlo in cmdline. Sembrerebbe che (?! e (?= siano funzioni inserite
dal perl5 e quindi non so se awk sed egrep lo supportino, e con sed
come quotarlo. Con perl invece non so come metterlo in pipe (premetto
che non conosco il perl).
# echo y|egrep '(?!x).'
non produce output, mentre messa in kregexpeditor si
in perl come si mette?
# echo y|perl -e '/y/'
non funge...
insomma, ora che sembra che abbia trovato la regex non riesco ad
utilizzarla :-(
Matteo

CE L'HO FATTAAA!!
greppo, anzi, perlo sul vocabolario di aspell.
1)
$ cat aspellit |perl -ne 'if ( m/^(.)((?!\1).)\2\1$/ ) { print "$_"; }'
abba acca adda alla anna arra atta ....
2)
$ cat aspellit |perl -ne 'if ( m/^(.)((?!\1).)\2((?!\1|\2).)$/ ) { print 
"$_"; }'
... uggi uggo unni unno urra uzza uzze uzzo week zoom
3)
$ cat aspellit |perl -ne 'if ( m/^(.)((?!\1).)\1\1\2$/ ) { print "$_"; }'
cacca cocco lilli mamma mimmi nanna nonno pappa poppo sesse tatta tette
4)
$ cat aspellit |perl -ne 'if ( m/^(.)((?!\1).)\1\1((?!\2).)$/ ) { print 
"$_"; }'
babbo cicca cocca lilla mamme mimmo nanne nonna pippo poppi sassi sasso 
tatto tetti tutto ...
5)
$ cat aspellit |perl -ne 'if ( 
m/^(.)((?!\1).)((?!\1|\2).)((?!\1|\2|\3).)((?!\1|\2|\3|\4).)((?!\1|\2|\3|\4|\5).)((?!\1|\2|\3|\4|\5|\6).)((?!\1|\2|\3|\4|\5|\6|\7).)((?!\1|\2|\3|\4|\5|\6|\7|\8).)((?!\1|\2|\3|\4|\5|\6|\7|\8|\9).)$/ 
 ) { print "$_"; }'
sono più di duemila.. parole di 10 caratteri senza duplicati: apicultore 
baroneschi calpestino censuriamo custodirle
insomma, svelo lo scopo: il classico "ad ogni numero uguale corrisponde 
lettera uguale" quindi dato un "pattern" di numeri lo script deve tirare 
fuori tutte le parole corrispondenti.
quindi
1) 1221
2) 1223
3) 12112
4) 12113
5) 0123456789
vediamo 1223455678, cioè una parola di 10 lettere con 2 doppie, che verrà 
fuori?
1= (.)
2= ((?!\1).) ovvero 'non \1'
2= \2
3= ((?!\1|\2).) ovvero 'non \1 non \2'
4= ((?!\1|\2|\3).) ovvero 'non \1 non \2 non \3'
5= ((?!\1|\2|\3|\4).) ovvero 'non \1 non \2 non \3 non \4'
5= \5
6= ((?!\1|\2|\3|\4|\5).) ovvero 'non \1 non \2 non \3 non \4 non \5'
7= ((?!\1|\2|\3|\4|\5|\6).) ovvero 'non \1 non \2 non \3 non \4 non \5 non 
\6'
8= ((?!\1|\2|\3|\4|\5|\6|\7).) ovvero 'non \1 non \2 non \3 non \4 non \5 
non \6 non \7'
quindi
$ cat aspellit |perl -ne 'if ( 
m/^(.)((?!\1).)\2((?!\1|\2).)((?!\1|\2|\3).)((?!\1|\2|\3|\4).)\5((?!\1|\2|\3|\4|\5).)((?!\1|\2|\3|\4|\5|\6).)((?!\1|\2|\3|\4|\5|\6|\7).)$/ 
 ) { print "$_"; }'
abbruttesi abbruttile abbruttilo abbruttine abbruttivo affliggevo afflissero 
affrettino aggressivo aggruppino agguerrilo agguerrito agguerrivo annuissero 
appressino apprettino apprezzino attrezzino attruppino oppressiva
Bene.
Ora devo fare lo script che mi genera la regex a partire dal pattern.
Credo che sia molto semplice.
Matteo