Newsgroup: it.comp.os.linux.iniziare
Titolo: Problemi con "sed" in script

Ho un problema con SED con i numeri negativi. Se lancio questo comando direttamente in BASH, mi funziona:
 
tac /temperatura.log/logDHT|head -n 744|grep -m1 -w "\-1.8"
 
Se invece lo inserisco in uno script non funziona. Ho provato già a mettere i "\" di escape, apici, doppi apici per racchiudere $T_MIN_MESE, ma niente. Non funziona Lo script è questo qui sotto.
 
T_MIN_MESE=-1.8
RIGA=`tac /temperatura.log/logDHT|head -n 744|grep -m1 -w "\$T_MIN_MESE"`
echo T_MIN_MESE: $T_MIN_MESE
echo RIGA: $RIGA
 
Qualcuno sa dirmi come passare sto valore negativo all'opzione "-w" di SED?
 
Grazie a tutti.


Anzitutto parliamo di "grep", non di "sed" che non
è utilizzato nel tuo script...
 
Non penso che "quel valore negativo" sia argomento
dell'opzione "-w". Non c'entra niente: se levi
l'opzione "-w" il problema resta.
Inoltre a me il problema si presenta sia da riga di
comando che via script.
 
Il succo del problema è come hai capito anche tu il
*pattern* che inizia per "meno", in quanto grep inter-
cetta questo carattere come "opzione" e si aspetta poi
l'argomento finale, cioè il pattern che evidentemente
è assente...
 
Funziona l'escape col backslash solo se il pattern
è esplicito, ad esempio "\-1.8" oppure "\-10" ecc.
Ma se il pattern è memorizzato in una variabile, come
fai nello script, ecco che non funziona più.
Questo no dipende dal fatto di dare il comando dentro
lo script o fuori... non c'entra: non funziona in entrambi
i casi.
 
Considera il seguente esempio, che funziona:
------------------------------------------
rigadicomando:$ echo -e 'a\nb\nc\nd\n-10'
a
b
c
d
-10
rigadicmoando:$ echo -e 'a\nb\nc\nd\n-10'|grep "\-10"
-10
----
 
Ora prova a lavorare con un pattern memorizzato in una
variabile chiamata con molta fantasia PATTERN:
----------------------------------------------
rigadicomando:$ PATTERN=-10
rigadicomando:$ echo -e 'a\nb\nc\nd\n-10'|grep $PATTERN
Uso: grep [OPZIONE]... MODELLO [FILE]...
Usare "grep --help" per ulteriori informazioni.
-----------------------------------------------
non funziona...
Vediamo una forma che funziona (finalmente)
-------------------------------------------
echo -e 'a\nb\nc\nd\n-10'|grep \\$PATTERN
-10
-------------------------------------------
 
Il doppio back-slash funziona. Come:
il primo b-slash inibisce il secondo, in modo
che quest'ultimo non inibisca il dollaro che
deve essere interpretato dalla shell come carattere
di espansione della variabile PATTERN.
 
Per vedere come la bash interpreta questi comandi
passo passo, puoi dare il comando:
 
set -x
 
in questo modo tu lanci qualsiasi comando e la shell
"ripete" il comando mostrandoti come lo interpreta
letteralmente:
---------
$ set -x
 
$ echo -e 'a\nb\nc\nd\n-10'|grep $PATTERN
+ grep -10
+ echo -e 'a\nb\nc\nd\n-10'
Uso: grep [OPZIONE]... MODELLO [FILE]...
Usare "grep --help" per ulteriori informazioni.
 
$ echo -e 'a\nb\nc\nd\n-10'|grep \$PATTERN
+ echo -e 'a\nb\nc\nd\n-10'
+ grep '$PATTERN'
 
$ echo -e 'a\nb\nc\nd\n-10'|grep \\$PATTERN
+ echo -e 'a\nb\nc\nd\n-10'
+ grep '\-10'
-10
-------------
 
Nel primo caso l'espansione della variabile senza
escape provoca un "grep -10" che come abbiamo detto
grep non riesce a gestire.
 
Nel secondo caso, signolo b-slash viene inibito il
dollaro e la variabile non viene espansa così il
pattern che cerca grep sarà testualmente $PATTERN.
Il comando in questo caso è corretto come sintassi,
l'errore è "semantico"... stiamo cercando una cosa
diversa da quella che dobbiamo cercare e che crediamo
di cercare...
 
Nel terzo caso il doppio b-slash fa il suo sporco
lavoro. Il primo inibisce l'effetto del secondo sul
dollaro.
E questa soluzione funziona anche se ti crei lo script
e vi inserisci il comando...
 
 
 
Tuttavia c'era un'alternativa forse più pulita e meno
cervellotica...
C'è un modo per comunicare ad un comando, non solo
a grep, che le opzioni che abbiamo passato al comando
sono concluse e che da lì in avanti, gli ulteriori
argomenti sono effettivamente argomenti, non più da
interpretare quindi come opzioni.
Per lo scopo si usa la forma:
 
grep [opzioni] -- <pattern> <inputfile>
 
Il doppio trattino "meno meno" dice a grep che ciò
che segue (cioè il pattern) è da interpretare non
come opzione ma come argomento (cioè come pattern)
indipendentemente dal fatto che inizi con il trattino.
 
Esempio
 
grep -- -10 provagrep.txt
 
o in cascata ad un output con la pipe:
 
echo -e 'a\nb\nc\nd\n-10'|grep -- -10
 
In questo modo, il '-10' pur essendo una stringa che
inizia col trattino, non viene più interpretata come
opzione da grep, ma come argomento, che in questo caso
è il primo, quindi viene interpretato come pattern.
 
Questo comportamento non sono sicurissimissimo che
funzioni su tutti i tipi di shell, ma nella bash
sicuro. Dal "man bash":
-------------------------------------------------
--        A  --  signals  the end of options and
          disables further option processing. Any
	  arguments after the -- are treated as
	  filenames and arguments.  An argument
	  of - is equivalent to --
------------------------------------------------
 
Se non ho capito male il doppio trattino è equivalente
al singolo trattino (questo non lo ricordavo...).
 
Provando:
---------
$ echo -e 'a\nb\nc\nd\n-10'|grep - -10
+ echo -e 'a\nb\nc\nd\n-10'
+ grep - -10
-10
 
$ echo -e 'a\nb\nc\nd\n-10'|grep - $PATTERN
+ echo -e 'a\nb\nc\nd\n-10'
+ grep - -10
-10
---
 
In effetti funziona anche col trattino singlo.
È importante notare che l'impiego di "--" o "-"
funziona con tutti i programmi da riga di comando,
grep sed ls cd touch cat ecc ecc...
 
 
 
 
PS.
Il "set -x", che attiva di fatto una sorta di modalità debug,
se lo dai da linea di comando, poi per toglierlo e tornare
alla riga di comando in modalità normale diciamo, deivi dare:
 
set +x
 
Invece se lo usi in uno script posto ad esempio in testa:
----------
#!/bin/sh
set -x
-------
influenza solo l'esecuzione dello script... cioè quando lo
script finisce e torni alla riga di comando, questa sarà in
modalità normale come in partenza.
 
Ho scritto più 200 righe!!!
Stavo aspettando una mail... e mi sono fatto prendere dal
post.  :D
Bastava molto meno...
 
Saluti e già che ci siamo, felice anno nuovo a tutti!

Ciao Joe.
 
Intanto mi scuso per aver sbagliato l'oggetto del POST.
In effetti il problema era con GREP e non con SED.
 
Secondo, ti ringrazio tantissimo per tutto quello che hai scritto.
Ho fatto un po' di prove e alla fine ho risolto mettendo nel mio script così:
 
........ grep -m1 -w -- "\$T_MAX"`
 
Grazie ancora e Buon Anno


Altrettanto, passatela bene anche te!  :)
Ciao!