Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.

Autor Téma: Bude na tohle stačit sed?  (Přečteno 1124 krát)

klasyc

  • Člen
  • **
  • Příspěvků: 470
    • Zobrazit profil
Bude na tohle stačit sed?
« kdy: 21 Říjen 2009, 22:45:29 »
Zdravím místní komunitu linuxářů, kteří se orientují trochu v shellu, regulárních výrazech a sedu.
Dělám si skript na stažení předpovědi počasí a uložení do databáze. Momentálně jsem ve fázi, kdy mám v souboru tohle:

wgtabd1_DAY=new Array('St,21,1','St,21,1','St,21,1','St,21,1','Čt,22,0','Čt,22,0','Čt,22,0','Čt,22,0','Čt,22,0','Čt,22,0','Čt,22,0','Čt,22,0','Pá,23,1','Pá,23,1','Pá,23,1','Pá,23,1','Pá,23,1','Pá,23,1','Pá,23,1','Pá,23,1','So,24,0','So,24,0','So,24,0','So,24,0','So,24,0','So,24,0','So,24,0','So,24,0','Ne,25,1','Ne,25,1','Ne,25,1','Ne,25,1','Ne,25,1','Ne,25,1','Ne,25,1','Ne,25,1','Po,26,0','Po,26,0','Po,26,0','Po,26,0','Po,26,0','Po,26,0','Po,26,0','Po,26,0','Út,27,1','Út,27,1','Út,27,1','Út,27,1','Út,27,1','Út,27,1','Út,27,1','Út,27,1','St,28,0','St,28,0','St,28,0','St,28,0','St,28,0','St,28,0','St,28,0','St,28,0','Čt,29,1',',');
wgtabd1_HR=new Array('14,1','17,1','20,1','23,1','02,0','05,0','08,0','11,0','14,0','17,0','20,0','23,0','02,1','05,1','08,1','11,1','14,1','17,1','20,1','23,1','02,0','05,0','08,0','11,0','14,0','17,0','20,0','23,0','02,1','04,1','07,1','10,1','13,1','16,1','19,1','22,1','01,0','04,0','07,0','10,0','13,0','16,0','19,0','22,0','01,1','04,1','07,1','10,1','13,1','16,1','19,1','22,1','01,0','04,0','07,0','10,0','13,0','16,0','19,0','22,0','01,1',',');
wgtabd1_APCP=new Array('_',0,0,0,0,0.1,0,0.1,0.1,0.1,0.1,0.9,3,5.4,0.1,0,0,0,0,0,0,0.1,0,0,0,0,0,0,0,0,0,0,0,0.2,3.2,0.3,-0,0,0,0,0,0,0,0,0,0,-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

A potřeboval bych ta pole přepsat do formy SQL insertů - něco ve smyslu

INSERT INTO tabulka (den, hodina, srazky) values(hodnota_z_prvniho_pole, hodnota_z_druheho_pole, hodnota_z_tretiho_pole)
(na každej prvek pole jeden insert.

Je tu nějakej frajer, co to umí udělat jen v shellu třeba pomocí sedu a nebo si mám napsat v céčku binárku na převod?

premet

  • Host
Re: Bude na tohle stačit sed?
« Odpověď #1 kdy: 21 Říjen 2009, 23:03:47 »
Jen tak v rychlosti a krátce mě napadá použití awk (nejsem si jist jestli to takhle lze použít s tím oddělovačem, ale vypadá to, že to funguje), ale nevím co přesně chceš z toho postupně dostat, ale zkus mrknout na tohle
Kód: [Vybrat]
[prema@fedora ~]$ echo "17,1','20,1','23,1','02,0" | awk -F\',\' '{print $1}'
17,1
[prema@fedora ~]$ echo "17,1','20,1','23,1','02,0" | awk -F\',\' '{print $2}'
20,1

nebo takhle
Kód: [Vybrat]
[prema@fedora ~]$ echo "17,1','20,1','23,1','02,0" | awk -F"','" '{print $1}'
17,1
čili to co je za -F je použito jako oddělovač a pak $1 ... $n jsou pak ty výrazy mezi oddělovači
« Poslední změna: 21 Říjen 2009, 23:06:40 od Kotrmelec »

nettezzaumana

  • Host
Re: Bude na tohle stačit sed?
« Odpověď #2 kdy: 21 Říjen 2009, 23:58:58 »
hehe. doporucuju si napsat v c tu binarku :D

klasyc

  • Člen
  • **
  • Příspěvků: 470
    • Zobrazit profil
Re: Bude na tohle stačit sed?
« Odpověď #3 kdy: 22 Říjen 2009, 00:20:09 »
hehe. doporucuju si napsat v c tu binarku :D
Tak zrovna od velkého ntz bych tohle nečekal!!! No co se dá dělat. Tady je ta "binárka". Bolelo to, ale chodí. Je to moje asi druhé dílo v bashi v životě, tak mě prosím nekamenujte. Třeba se to někdy bude někomu hodit....

Kód: [Vybrat]
#!/bin/bash

# URL, ktere se predava pri prihlasovani na stranku:
LOGIN_URL=

# Jmeno predpovedniho mista, ktere se ma po prihlaseni hledat:
MISTO=

# Cesta k programu wget:
WGET='/usr/bin/wget'

# Docasny adresar s pravem zapisu pro nas skript:
TMP='/tmp'

# Hlavicka SQL skriptu, ktery se bude vkladat do databaze:
HLAVICKA='vymazStareSrazky();'



# --- Tady uz zacina samotny kod: ---

# Smazeme stary soubor s daty, pokud existuje:
if [ -f ${TMP}/wgindex.html ]; then
  echo "Mažu starý soubor s předpovědí...";
  rm ${TMP}/wgindex.html -f;
fi

# Prejdeme wgetem na zadane logovaci URL, prihlasime se a ulozime si cookies:
echo "Stahuji předpověď na www.windguru.cz..."
$WGET --cookies=on --keep-session-cookies --save-cookies=${TMP}/wgcookies \
     $LOGIN_URL -q -O /dev/null

# Stahneme si indexovou stranku Windguru - ted uz s nactenim udaju po (doufejme)
# uspesnem prihlaseni:
$WGET --referer=${LOGIN_URL} --cookies=on --load-cookies=${TMP}/wgcookies \
      --keep-session-cookies --save-cookies=${TMP}/wgcookies -q \
      http://www.windguru.cz -O ${TMP}/wgindex.html

# Zkontrolujeme, jestli existuje zadany vystupni soubor:
if [ -f ${TMP}/wgindex.html ]; then
  echo "Data byla úspěšně stažena, hledám požadované předpovědní místo...";
 
  # Zkontrolujeme, jestli data obsahuji predpovedni misto, ktere jsme chteli
  # stahnout. Pokud ne, tak je pravdepodobne, ze prihlaseni selhalo a my mame
  # na vyber z tech prednastavenych mist...
 
  # Pres predpovedni misto pridame jednoduche uvozovky - tim se najde na strance
  # presne ten vyskyt textu, ktery potrebujeme:
  MISTO="'$MISTO"
 
  if grep -A 20 "$MISTO" ${TMP}/wgindex.html > ${TMP}/wgdata; then
    echo "Požadovaný vzorek nalezen, začíná parsování dat...";
   
    # Vygrepujeme si postupne dny v tydnu, hodina a mnozstvi srazek:
    grep 'wgtabd1_DAY=' ${TMP}/wgdata > ${TMP}/wgpocasi;
    grep 'wgtabd1_HR=' ${TMP}/wgdata >> ${TMP}/wgpocasi;
    grep 'wgtabd1_APCP=' ${TMP}/wgdata >> ${TMP}/wgpocasi;
   
    # Ze vznikleho souboru vyhazime vsechen prebytecnej bordel a nechame tam jenom
    # hodnoty oddelene carkami. Prvni radek jsou dny, druhy hodiny, treti dest:
    sed -e "s/'St,\|'Čt,\|'Pá,\|'So,\|'Ne,\|'Po,\|'Út,\|,1'\|,0'//g" -e "s/'//g" -e "s/^.*(//" -e "s/);$//" \
        ${TMP}/wgpocasi > ${TMP}/wgdata

    # Vytvorime vystupni soubor pro data SQL:
    echo $HLAVICKA > ${TMP}/wgout
    cat ${TMP}/wgdata
    # Cyklem projdeme vsechny "sloupce" v souboru a udelame z toho SQL prikazy:
    for SLOUPEC in `seq 1 60`; do
      # Prevedeme sloupecek dat do podoby sql:
      S=`cut -f${SLOUPEC} -d, ${TMP}/wgdata | tr -s '\n' ',' | sed -e "s/\([0-9]*\),\([0-9]*\)\,\(-*[0-9\.]*\),/pridejSrazky(\1, \2, \3);\n/"`;

      # Zkontrolujeme, jestli se to povedlo - tj. obsahuje to text pridejSrazky
      if echo $S | grep -q "pridejSrazky"; then
        # Pokud je to OK, tak se prida radek do souboru:
        echo "Exportuji předpověď č. ${SLOUPEC}..."
        echo $S >> ${TMP}/wgout;
      else
        # Pokud je obsah promenne pofiderni, tak se radsi ukladat nebude:
        echo "Předpověď č. ${SLOUPEC} nebyla rozpoznána a proto byla přeskočena."
      fi;
    done
   
    # Hotovo:
    rm -f wgdata wgpocasi
    echo "Parsování souboru dokončeno. Nyní bude proveden import do databáze."
  else
    echo "Předpovědní místo nebylo nalezeno. Bylo LOGIN_URL správné?";
    exit 2;
  fi;

else
  echo "Data se nepodařilo stáhnout. Zkontrolujte připojení a LOGIN_URL.";
  exit 1;
fi

nettezzaumana

  • Host
Re: Bude na tohle stačit sed?
« Odpověď #4 kdy: 22 Říjen 2009, 01:03:31 »
co cekas je tvuj problem. nicmene ja to nepochopil.
priste ukaz presnej vstup a presnej vystup jak ho potrebujes ..

nettezzaumana

  • Host
Re: Bude na tohle stačit sed?
« Odpověď #5 kdy: 22 Říjen 2009, 08:47:22 »
@klasyc .. btw, kamenovat te rozhodne nechci, ale nepojmenovavej ve svych skriptech promenne VELKYMA pismenama .. system je tak ma. normalne se to nedela, neni to dobra praxe ..

klasyc

  • Člen
  • **
  • Příspěvků: 470
    • Zobrazit profil
Re: Bude na tohle stačit sed?
« Odpověď #6 kdy: 22 Říjen 2009, 13:18:48 »
No přesnej vstup je to, co sem psal v prvním příspěvku - akorát ten můj skript to na začátku stáhne wgetem, hodí na to jeden grep a pak už je to přesně to, co jsem psal.
Jinak dík za upozornění ohledně pojmenování proměnných - nechtělo se mi nic stahovat, tak jsem se učil ze systémových skriptů, tak proto ta velká písmena :D