Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Wie helpt mij met het sed commando ?  (gelezen 1089 keer)

Offline zanco

  • Lid
Wie helpt mij met het sed commando ?
« Gepost op: 2010/06/20, 20:38:16 »
Ik gebruik een Linux Bash script om een (zendamateur) radio aan te sturen. Ik lees via een webpagina in welke frequentie er wordt gekozen met radiobuttons en d.m.v. sed wordt die frequentie in een variabele gestopt en via rigctl naar de radio gestuurd. Nu wil ik behalve de frequentie ook nog de mode en bandbreedte meesturen.
 
Dat betekent dus dat het commando waarbij F (voor frequentie) gevolgd door variabele wordt gestuurd (dus F 144500000 ) moet nu F 144500000 M USB 0 gaan sturen.
Het sed commando wat ik nu gebruik maakt er echter 14450000+M+USB+0 van en ik heb geen idee waar ik het moet zoeken.
 
De huidige sed opdracht is door mijn broer ergens uit een tutorial gehaald en voldeed voor alleen de frequentie wel.
 
Hieronder het voorbeeld wat de frequentie in een variabele ZZ plaatst:
 
<input type="radio" name="val_z" value="145312500"> geeft met
ZZ=`echo "$QUERY_STRING" | sed -n 's/^.*val_z=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` keurig 145312500 als waarde in ZZ
 
Nu verwachtte ik dat met %20 werd gezocht naar het laatste cijfer van de input, dus dat verklaarde dat het niet werkte als ik value="145312500 M USB 0" toepaste, dan werd nog steeds alleen de Frequentie gestuurd omdat hij bij de eerste spatie stopt. Ik heb dus %20 vervangen door %21 (het uitroepteken) en sluit dan de value af met een uitroepteken., zoals hieronder:
 
<input type="radio" name="val_z" value="145212500 M USB 0!"> maar dit geeft dan met
 
YY=`echo "$QUERY_STRING" | sed -n 's/^.*val_z=\([^&]*\).*$/\1/p' | sed "s/%21/ /g"` 145312500+M+USB+0 terwijl ik daar gewoon spaties tussen nodig heb in plaats van het + symbool.

Kan iemand een toelichting geven wat het sed commando in de eerste regel (die met ZZ begint) precies doet zodat ik kan bedenken hoe ik het aan moet passen om in de regel met YY wel de juiste info in de variabele YY te krijgen ?

Bedankt,

Ben

Re: Wie helpt mij met het sed commando ?
« Reactie #1 Gepost op: 2010/06/21, 15:45:21 »
Hmm, da's een heel raar sed-commando...

sed -n betekent dat hij niets print.

s/a/b/p betekent "vervang a door b en print deze regel"
^.*val_z=\([^&]*\).*$ is een regex.
^ betekent begin van de regel
.* betekent ieder karakter, 0 keer of meer.
\(\) wordt gebruikt om straks te refereren naar wat er tussen staat (zie \1)
[^&]* betekent ieder karakter, behalve &, 0 keer of meer.
$ betekent einde van de regel
\1 betekent de tekst die tussen de eerste \(\) stond.

s/%21/ /g betekent "vervang iedere '%21' door ' '."

Okee, ik denk niet dat dat is wat je wilt...

zou dit misschien helpen?
YY=`echo "$QUERY_STRING"` | grep -e 'input.*name="val_z"' | head -n1 | sed -n 's/^.*value="\(.*\)".*$/\1/p`

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline zanco

  • Lid
Re: Wie helpt mij met het sed commando ?
« Reactie #2 Gepost op: 2010/06/21, 22:48:25 »
Hai,
bedankt voor de snelle reactie en de uitleg.

Als ik het voorgestelde commando draai vanaf de command prompt dan krijg ik als reactie alleen een > op het scherm te zien, met ctrl-c kom ik daar weer uit terug in de command line. Zie onderstaand het geplakte resultaat.


ben@ontwikkeldoos:/var/www/cgi-bin$ echo "145500000 M USB 0"` | grep -e 'input.*name="val_z"' | head -n1 | sed -n 's/^.*value="\(.*\)".*$/\1/p
>



Inmiddels heb ik nog een andere oplossing aangereikt gekregen, waarbij de tekst in rood de tekst van mij is en de rest de reactie:

dus het commando waarbij F (voor frequentie) variabele wordt gestuurd (dus F 144500000 ) moet nu F 144500000 M USB 0 gaan sturen.
Het sed commando wat ik gebruik maakt er echter 14450000+M+USB+0 van en ik heb geen idee waar ik het moet zoeken.



Het probleem is dat browsers spaties coderen als '%20' of als '+', je moet dus de input die je van de webserver krijgt dus enigzins bewerken om dat zo te krijgen.


<input type="radio" name="val_z" value="145312500"> geeft met
ZZ=`echo "$QUERY_STRING" | sed -n 's/^.*val_z=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` keurig 145312500 als waarde in ZZ



Wat de 'ZZ' regel doet is het ontvangen van de parameters  in HTTP GET call, de QUERY_STRING. Daar staat dan in:


z_val=145312500


eventueel met meerdere parameters, dan kan het dus ook zijn


z_val=145312500&nog_een=23123213&nog_twee=131231


Die wordt eerst ge-echod en door de eerste sed aanroep geparsed. Die zoekt naar 'val_z=' en alles wat daarna volgt dat geen '&' is wordt opgeslagen in match parameter 1. De hele regel wordt gematched en vervangen door die eerste match. Dus in het geval van mijn tweede voorbeeld wordt het dan:


[pjoe@mbpjoe]~$ echo "val_z=145312500&nog_een=23123213&nog_twee=131231" | sed -n 's/^.*val_z=\([^&]*\).*$/\1/p'                 
145312500


Wat de tweede sed doet is alle http encoded spaties vervangen door gewone spaties. Dus stel dat je waarde van z_val


'14450000 M USB 0'


is, dan wordt dat door de browser en de webserver omgevormd naar
'14450000%20M%20USB%200'


Het tweede sed commando maakt daar dan weer van:


'14450000 M USB 0'


Maar het komt dus ook voor dat sommige browsers en webservers er dit van maken


'14450000+M+USB+0'


Om die dus goed te krijgen moet je er nog een sed script aan toevoegen:


ZZ=`echo "$QUERY_STRING" | sed -n 's/^.*val_z=\([^&]*\).*$/\1/p' | sed "s/%20/ /g" | sed "s/\+/ /g"`


Die laatste sed vervangt ook de plusjes door spaties, die backslash moet ervoor omdat de plus gebruikt wordt als speciaal karakter. Als die plus er niet staat dan betekent het 'voorgaande karakter 1 of meer keer'.


[pjoe@mbpjoe]~$ echo "14450000+M+USB%200" | sed 's/%20/ /g' | sed 's/\+/ /g'
14450000 M USB 0


En inderdaad werkt dat zoals ik het wil.

Grtz,
Ben