Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: Cendas 25 Prosince 2011, 13:26:32
-
Ahoj tohle používám na načtení proměnných.
eval`head -10 $HOUR_FILE| grep "location" | sed 's/<location *\(.*"\) *\/>/\1/'`
Ale jeden řádek je moc dlouhý a příkaz grep mi vypíše místo tohohle:
<location altitude="307" latitude="50.92139" longitude="15.07974" geobase="geonames" geobaseid="3076124" />
tohle:
altitude="307" latitude="50.92139" longitude="15.07974" geobase="geonames" geob
</location>24"
Nevěděl by někdo jak to udělat aby to ten řádek vypsalo celí?
-
Tady není problém s dlouhým řádkem, dej k dispozici vzorek dat, které zpracováváš, pokud ti s tím má někdo pomoct.
-
Jasně tady je celí ten ten kousek scriptu co jsem zatím vymyslel.
Je to zatím jen získání dat s xml souboru.
Nefunguje jen ten řádek s location.
#!/bin/bash
STATE_CITY=Czech_Republic/Liberec/Frýdlant~3076124
wget -O forecast.xml http://www.yr.no/place/$STATE_CITY/forecast.xml
wget -O hour.xml http://www.yr.no/place/$STATE_CITY/forecast_hour_by_hour.xml
FORECAST_FILE=forecast.xml
HOUR_FILE=hour.xml
CITY=`head -6 $HOUR_FILE| grep "name" | sed 's/<.*>\(.*\)<.*>/\1/'`
COUNTRY=`head -6 $HOUR_FILE| grep "country" | sed 's/<.*>\(.*\)<.*>/\1/'`
eval`head -10 $HOUR_FILE| grep "location" | sed 's/<location *\(.*"\) *\/>/\1/'`
LOCATION_LATITUDE=$latitude
LOCATION_LONGITUDE=$longitude
SUN_RISE=`head -40 $HOUR_FILE | grep "set="| cut -c 25-32`
SUN_SET=`head -40 $HOUR_FILE | grep "set="| cut -c 51-58`
VALID_FROM=`head -40 $HOUR_FILE | grep "time from="| cut -c 30-37`
eval`head -40 $HOUR_FILE| grep "symbol number=" | sed 's/<symbol *\(.*"\) *\/>/\1/'`
SIMBOL_NUMBER=$number
SIMBOL_NAME=$name
SIMBOL_VAR=$var
eval `head -40 $HOUR_FILE| grep "precipitation" | sed 's/<precipitation *\(.*"\) *\/>/\1/'`
PRECIPITATION_VALUE=$value
PRECIPITATION_MINVALUE=$minvalue
PRECIPITATION_MAXVALUE=$maxvalue
eval `head -40 $HOUR_FILE| grep "windDirection" | sed 's/<windDirection *\(.*"\) *\/>/\1/'`
WIND_DIRECT_DEG=$deg
WIND_DIRECT_CODE=$code
WIND_DIRECT_NAME=$name
eval `head -40 $HOUR_FILE| grep "windSpeed" | sed 's/<windSpeed *\(.*"\) *\/>/\1/'`
WIND_SPEED_MPS=$mps
WIND_SPEED_NAME=$name
eval `head -40 $HOUR_FILE| grep "temperature" | sed 's/<temperature *\(.*"\) *\/>/\1/'`
TEMPERATURE_UNIT=$unit
TEMPERATURE_VALUE=$value
eval `head -40 $HOUR_FILE| grep "pressure" | sed 's/<pressure *\(.*"\) *\/>/\1/'`
PRESSURE_UNIT=$unit
PRESSURE_VALUE=$value
echo $CITY
echo $COUNTRY
echo $SUN_RISE
echo $SUN_SET
echo $VALID_FROM
echo $SIMBOL_NUMBER
echo $SIMBOL_NAME
echo $SIMBOL_VAR
echo $WIND_DIRECT_DEG
echo $WIND_DIRECT_CODE
echo $WIND_DIRECT_NAME
echo $PRECIPITATION_VALUE
echo $PRECIPITATION_MINVALUE
echo $PRECIPITATION_MAXVALUE
echo $WIND_SPEED_MPS
echo $WIND_SPEED_NAME
echo $TEMPERATURE_UNIT
echo $TEMPERATURE_VALUE
echo $PRESSURE_UNIT
echo $PRESSURE_VALUE
echo $LOCATION_LATITUDE
echo $LOCATION_LONGITUDE
exit
-
Chtěl jsem data především, tys dodal jen skript. Každopádně vidím, že vygrepuješ location přinejmenším na dvou řádcích, přičemž ten s tím ukončovacím tagem zřejmě nepotřebuješ. Musíš správně upravit regulární výraz.
-
Data jsou tady.
http://www.yr.no/place/Czech_Republic/Liberec/Fr%C3%BDdlant~3076124/forecast_hour_by_hour.xml
-
Už jsem to vyřešil takhle. :)
eval `sed -n '8p' $HOUR_FILE | sed 's/<location *\(.*"\) *\/>/\1/'`
Ještě bych se rád zeptal jestli by to nešlo napsat tak abych sed mohl použít jen jednou?
-
Promiň, nekoukl jsem se pořádně, linky přehlédl. Nicméně nevidím jiný problém, než ten o kterém jsem psal a nechápu ten head -10, který aktálně ustřihne i užitečná data. Když už jsme u toho, ani grep není potřeba, na stávající soubor stačí jen sed:
sed -n 's/<location *\(.*"\) *\/>/\1/'p
EDIT: tedy ten head odstřihne užitečná data jen v tom samostatně odkazovaném souboru, každopádně to není pěkné řešení.
-
Jo dík takhle je to fajn. Ten zbytek dat odstřihávám protože chci akuální předpověď počasí. Je to tam rozdělené po hodině tak ty předpovědi na další hodiny nepotřebuji. Mám to totiž do conky a vše by se tam nevešlo. Ale když vždy načtu jen konkrétní řádek tak pak bych opravdu head nepotřeboval.
-
Nicméně tento údaj je tam jen jednou, takže je head zbytečný. V tom xml jsou na začátku mezery, které nevadí, ale dokonalejší je to takto:
sed -n 's/ *<location *\(.*"\) *\/>/\1/'p
Jinak tam asi desetkrát čteš ze souboru se stejným head, načti si to jednou do proměnné a tu pak použij na všechny ostatní selekce.
-
Jo máš pravdu taky mě to mohlo hned napadnout. ;)
-
Jeste jeden tip na parsovani xml:
[donny] ~ $ xmllint
Usage : xmllint [options] XMLfiles ...
Parse the XML files and output the result of the parsing
xmllint by mel byt v zakladni instalaci Ubuntu ( http://packages.ubuntu.com/natty/libxml2 )
-
Tak jsem ti to upravil. Klasická proměnná se tu použít nedá, uložil jsem tedy soubory do /dev/shm/, což je v RAM a tudíž se zbytečně neobtěžuje disk.
#!/bin/bash
STATE_CITY='Czech_Republic/Liberec/Frýdlant~3076124'
FORECAST_FILE='/dev/shm/forecast.xml'
HOUR_FILE='/dev/shm/hour.xml'
wget -O $FORECAST_FILE http://www.yr.no/place/$STATE_CITY/forecast.xml
wget -O $HOUR_FILE http://www.yr.no/place/$STATE_CITY/forecast_hour_by_hour.xml
sed -i '40q' $HOUR_FILE
sed -n 's/ *<name>\(.*\)<.*/\1/p' $HOUR_FILE
sed -n 's/ *<country>\(.*\)<.*/\1/p' $HOUR_FILE
sed -n 's/ *<sun .*rise="\([^"]*\)".*/\1/p' $HOUR_FILE | cut -c 12-16
sed -n 's/ *<sun .*set="\([^"]*\)".*/\1/p' $HOUR_FILE | cut -c 12-16
sed -n 's/ *<time .*from="\([^"]*\)".*/\1/p' $HOUR_FILE| cut -c 12-16
sed -n 's/ *<symbol .*number="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<symbol .*name="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<symbol .*var="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<windDirection .*deg="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<windDirection .*code="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<windDirection .*name="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<precipitation .*value="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<precipitation .*minvalue="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<precipitation .*maxvalue="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<windSpeed .*mps="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<windSpeed .*name="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<temperature .*unit="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<temperature .*value="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<pressure .*unit="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<pressure .*value="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<location .*latitude="\([^"]*\)".*/\1/p' $HOUR_FILE
sed -n 's/ *<location .*longitude="\([^"]*\)".*/\1/p' $HOUR_FILE
rm $FORECAST_FILE
rm $HOUR_FILE
-
Dík to jsi ani nemusel ale je to fajn.
Já to hlavně dělám taky proto abych se to naučil.
Můžeš mi napsat význam hranatých závorek a té stříšky v substituci?
A nebo jestli nevíš o nějakém odkazu kde by to bylo vysvětleno v češtině?
-
to jsou takzvané regulární výrazy, něco jako "maska". Začít můžeš třeba tady: http://www.regularnivyrazy.info/
-
Dík to jsi ani nemusel ale je to fajn.
Já to hlavně dělám taky proto abych se to naučil.
Můžeš mi napsat význam hranatých závorek a té stříšky v substituci?
A nebo jestli nevíš o nějakém odkazu kde by to bylo vysvětleno v češtině?
Však já to bral taky v rámci vzdělávání :)
Regulární výrazy jsou tzv žravé a tudíž výraz: ".*" vezme řetězec od prvních uvozovek, až po ty poslední na řádku, i když je tam těch uvozovek třeba tucet. Hranaté závorky umožňují definovat povolené znaky a pokud je uvedeš ^ (stříškou), invertuje se význam a jde tedy o zakázané znaky. Tedy v našem případě výraz [^"]* říká - odtud všechny znaky až po uvozovky.
-
Ahoj díky za vysvětlení.
Na odkaz jsem kouknul to se mi bude hodit.