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

Název: Grep a dlouhý řádek [vyřešeno]
Přispěvatel: 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í?
Název: Re:Grep a dlouhý řádek
Přispěvatel: GdH 25 Prosince 2011, 15:49:10
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.
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 25 Prosince 2011, 19:07:05
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.
Kód: [Vybrat]
#!/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
Název: Re:Grep a dlouhý řádek
Přispěvatel: GdH 25 Prosince 2011, 20:29:33
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.
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 26 Prosince 2011, 07:19:37
Data jsou tady.
http://www.yr.no/place/Czech_Republic/Liberec/Fr%C3%BDdlant~3076124/forecast_hour_by_hour.xml
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 26 Prosince 2011, 10:20:10
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?
Název: Re:Grep a dlouhý řádek
Přispěvatel: GdH 26 Prosince 2011, 10:24:19
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:

Kód: [Vybrat]
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í.
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 26 Prosince 2011, 10:42:34
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.
Název: Re:Grep a dlouhý řádek
Přispěvatel: GdH 26 Prosince 2011, 10:53:45
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:

Kód: [Vybrat]
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.
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 26 Prosince 2011, 10:56:24
Jo máš pravdu taky mě to mohlo hned napadnout.  ;)
Název: Re:Grep a dlouhý řádek
Přispěvatel: donny 26 Prosince 2011, 11:20:36
Jeste jeden tip na parsovani xml:

Kód: [Vybrat]
[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 )
Název: Re:Grep a dlouhý řádek
Přispěvatel: GdH 26 Prosince 2011, 14:51:00
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.

Kód: [Vybrat]
#!/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
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 26 Prosince 2011, 18:57:22
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ě?
Název: Re:Grep a dlouhý řádek
Přispěvatel: donny 26 Prosince 2011, 19:20:09
to jsou takzvané regulární výrazy, něco jako "maska". Začít můžeš třeba tady: http://www.regularnivyrazy.info/
Název: Re:Grep a dlouhý řádek
Přispěvatel: GdH 26 Prosince 2011, 19:45:07
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.
Název: Re:Grep a dlouhý řádek
Přispěvatel: Cendas 27 Prosince 2011, 10:04:07
Ahoj díky za vysvětlení.
Na odkaz jsem kouknul to se mi bude hodit.