-
Komennot datan käsittelyyn
Komennot datan käsittelyyn
Linux tarjoaa runsaasti työkaluja datatiedostojen tutkimiseen, suodattamiseen ja muokkaamiseen. Nämä työkalut ovat usein hyödyllisiä, kun datatiedostoja täytyy muuntaa muodosta toiseen tai kun suurista aineistoista täytyy poimia tiettyä dataa. Tavallisilla Linux-työkaluilla on kuitenkin rajoituksensa. Jos aiot tehdä monimutkaisempaa datanhallintaa, skriptikielet kuten Python ja Perl voivat olla tehokkaampia työkaluja. Numeerisen datan tapauksessa monet sovellusohjelmat, esimerkiksi R, tarjoavat työkaluja sekä monimutkaisiin analyysitehtäviin että analyysin automatisointiin.
grep valitsee rivit, jotka vastaavat annettua merkkijonoa
Komentoa grep käytetään rivien valitsemiseen tiedostosta. Tämä
komento on erittäin hyödyllinen datan poimimisessa suurista tiedostoista.
grep-komennon käyttö kuitenkin edellyttää, että tunnet hyvin käsittelemäsi
tiedoston sisällön. grep-komennon perussyntaksi on:
Tämä komento käy kohdetiedoston läpi ja tulostaa rivit, jotka
sisältävät annetun hakukuvion.
Oletetaan esimerkiksi, että meillä on tiedosto nimeltä authors.txt, joka sisältää
seuraavat rivit:
Tässä tapauksessa komento:
tulostaisi kaksi riviä:
koska myös Pekkanen vastaa hakumerkkijonoa Pekka. Jos haluamme käyttää hakumerkkijonona koko nimeä, mukaan lukien nimien välisen välilyönnin, meidän täytyy ympäröidä hakumerkkijono lainausmerkeillä. Esimerkiksi
tulostaa vain
Käänteinen valinta tehdään käyttämällä valitsinta -v. Esimerkiksi komento
tulostaa
Oletusarvoisesti grep erottaa isot ja pienet kirjaimet, joten komento
ei tuottaisi yhtään osumaa. Valitsimella -i grep ohittaa
isojen ja pienten kirjainten erot. Esimerkiksi
tulostaa jälleen
grep tulkitsee annetun hakumerkkijonon säännöllisenä lausekkeena, jossa
joillakin merkeillä on erityinen merkitys ja ne tulkitaan osaksi
säännöllisen lausekkeen merkkijonoa. Samaa säännöllisten lausekkeiden syntaksia
käytetään myös awk- ja sed-komennoissa. Esimerkiksi:
.määrittää minkä tahansa yksittäisen merkin^tarkoittaa rivin alkua$tarkoittaa rivin loppua[ ]vastaa mitä tahansa hakasulkeiden sisällä olevista merkeistä, joten esimerkiksi[abc]vastaisi merkkiä a, b tai c[^ ]vastaa mitä tahansa merkkiä paitsi hakasulkeiden sisällä olevia merkkejä, joten esimerkiksi[^abc]valitsisi kaikki rivit, jotka sisältävät myös muita merkkejä kuin vain a, b ja c*vastaa nollaa tai useampaa edeltävän merkin tai lausekkeen esiintymää\{n,m\}vastaa n:stä m:ään edeltävän merkin tai lausekkeen esiintymää
Esimerkiksi
tulostaa seuraavat kaksi riviä, koska hakuehtona on tässä tapauksessa i ja mikä tahansa muu merkki.
Tällaisissa tilanteissa voit käyttää kenoviivaa (\)
määrittämään, että seuraavaa merkkiä ei tule tulkita osaksi
säännöllistä lauseketta. Näin ollen komento
palauttaa nyt vain yhden rivin:
grep-komentoa käytetään usein muiden komentojen tulosteen suodattamiseen. Esimerkiksi
nähdäksemme, mitkä nykyisen hakemiston tiedostot ovat vuodelta
2010, voimme käyttää komentoa ls -l ja putkittaa sen grep-komennolle. grep:llä voimme
valita tulosteesta vain ne rivit, jotka sisältävät merkkijonon 2010.
Jotkin tiedostonimet voivat kuitenkin sisältää merkkijonon "2010", vaikka ne
eivät olisikaan vuodelta 2010. Suodatuksen tehostamiseksi voimme
käyttää lainausmerkkejä sisällyttämään vuoden numeron edessä ja jäljessä olevan
välilyönnin hakumerkkijonoon: ls -l | grep " 2010 ". Tavallisen
grep-komennon lisäksi on olemassa useita muita grep-tyyppisiä työkaluja. Esimerkiksi
zgrep- tai bzgrep-komentoja voidaan käyttää rivien etsimiseen
gzip- tai bzip2-pakatuista tiedostoista.
sed-komennon käyttö rivien valintaan rivinumeron perusteella
Virtamuokkainta sed voidaan käyttää rivien valintaan ja muokkaamiseen
tekstitiedostossa. Monet yllä kuvatuista grep-toiminnoista voidaan tehdä
myös sed:llä. sed-komentoa käsitellään tarkemmin luvussa
Sanojen ja merkkijonojen korvaaminen sed:llä.
Tässä näytämme vain, miten sed:iä voidaan käyttää tietyn rivin valintaan tiedostosta.
Esimerkiksi tiedoston authors.txt kolmas rivi voidaan valita
komennolla sed -n '3p' authors.txt Tässä tapauksessa tulos on
Pekka Niemi. Tampere 26. Tämä rivien poimintatapa on kätevä silmukoissa. Esimerkiksi
seuraava silmukka tulostaisi kolme riviä esimerkkitiedostosta:
Yksinkertainen sarakkeiden valinta cut-komennolla
Komento cut tarjoaa yksinkertaisen työkalun
merkkien alueiden (-c) tai sarakkeiden (-f) valintaan Linuxin
tekstitiedostosta. Kun valinta tehdään merkkipaikkojen perusteella, komennon syntaksi on:
Esimerkiksi komento
tulostaa tekstin kunkin authors.txt-tiedoston rivin toisesta viidenteen merkkiin.
Olettaen, että kyseessä on sama tiedosto, jota käytettiin yllä olevissa
grep-esimerkeissä, tuloste näyttää tältä:
Valitsimella -f voidaan tulostaa sarakkeita. Oletusarvoisesti sarkainta
käytetään sarake-erottimena. Muita erottimia voidaan määrittää
valitsimella -d. Esimerkiksi valitaksemme ensimmäisen ja kolmannen sarakkeen
(-f1,3) tiedostosta authors.txt, meidän täytyy määrittää välilyönti erottimeksi
(-d " "):
awk-komennon käyttö sarakkeiden käsittelyyn
awk on skriptikieli, jota voidaan käyttää tekstitiedostojen käsittelyyn
Linux-ympäristöissä. awk on melko vanha ohjelmointikieli,
ja nykyään datan hallintaskriptien tekemiseen käytetään tavallisesti
uudempia skriptaustyökaluja. Hyvin yksinkertaisen syntaksinsa vuoksi awk:ta
käytetään kuitenkin edelleen usein yksinkertaisiin suodatus- ja muokkaustehtäviin. Tässä
ohjeessa emme anna yleiskatsausta awk-ohjelmointiin.
Sen sijaan näytämme joitakin esimerkkejä siitä, miten awk:ta voidaan käyttää tiedostojen
kanssa tai osana Linuxin komentoputkia. Yksinkertaisessa komentorivikäytössä
awk-komennon perussyntaksi on:
awk:ta voidaan käyttää syötedatan käsittelyyn sarakkeina. Oletusarvoisesti awk
käyttää sekä välilyönti- että sarkainmerkkejä sarake-erottimina (huomaa, että toisin kuin
cut-komento, awk tulkitsee kaikki peräkkäiset välilyönnit yhdeksi ainoaksi sarake-erottimeksi).
Sarakkeisiin voidaan viitata awk:ssa muuttujilla $1
(ensimmäinen sarake), $2 (toinen sarake), $3 (kolmas sarake) jne. Muuttujaa $0
voidaan käyttää viittaamaan "kaikkiin sarakkeisiin". Esimerkiksi seuraava
komento tulostaa tiedoston authors.txt ensimmäisen ja kolmannen sarakkeen.
Yllä olevassa esimerkissä kenttiä ei eroteta tulosteessa toisistaan. Jotta
näin tapahtuisi, sinun täytyy lisätä välilyönti tai sarkainmerkki (\t) print-lauseeseen.
Voit myös lisätä tulosteeseen muuta tekstiä. Seuraava esimerkki
lisää tekstiä ja muuttaa sarakkeiden järjestystä:
$ awk '{print "Location: "$3"\t Name: "$1" "$2}' authors.txt
Location: Oulu Name: Eeva Pekkanen.
Location: Turku Name: Markus Aho.
Location: Tampere Name: Pekka Niemi.
Location: Kuopio Name: Leena Virtanen.
Hienostuneempi tapa tehdä yllä oleva muokkaus on käyttää
printf-komentoa print-komennon sijaan. awk printf -komennon
syntaksi on samanlainen kuin Linuxin printf-komennon.
Yksi awk:n hyvistä ominaisuuksista on, että komennossa voidaan käyttää
ehtolauseita. Voit vertailla sekä merkkijonoja että lukuja. Esimerkiksi
seuraava komento tulostaa dataa vain silloin, kun kolmas sarake on
"Tampere":
$ awk '{if ( $3 == "Tampere") print "Location: "$3"\tName: "$1" "$2}' authors.txt
Location: Tampere Name: Pekka Niemi.
Vaihtoehtoisesti ehto voidaan määrittää lauseosaaan ennen
awk-komentoja:
Jos sarakkeet sisältävät numeerisia arvoja, awk voi tehdä myös numeerisia
operaatioita. Käytetään esimerkiksi awk:ta laskemaan, kuinka paljon levytilaa
jpg-kuvatiedostot vievät nykyisessä kansiossa. Voimme ensin listata
jpg-tiedostot komennolla: ls -l *.jpg
$ ls -l *.jpg
-rw-------+ 1 kkayttaj csc 85112 Dec 19 2002 Image_2.jpg
-rw-r--r--+ 1 kkayttaj csc 105542 Nov 6 2006 Screen.jpg
-rw-r--r--+ 1 kkayttaj csc 167598 May 15 2008 casa1.jpg
-rw-------+ 1 kkayttaj csc 550031 Mar 25 2008 hexa.jpg
-rw-------+ 1 kkayttaj csc 869534 Dec 23 2005 img.jpg
-rw-------+ 1 kkayttaj csc 19159 Jul 23 2003 kuva.jpg
-rw-r-xr-x+ 1 kkayttaj csc 433268 Dec 23 2005 plot3.jpg
-rw-------+ 1 kkayttaj csc 1591444 Jan 26 12:27 copy.jpg
Summataksemme tiedostokokojen arvot viidennessä sarakkeessa putkitamme
tulosteen awk:lle:
$ ls -l *.jpg | awk '{total+=$5} END {print "JPG files in total: "total}'
JPG files in total: 3821688
Huomaa, että yllä olevassa awk-komennossa total on muuttujan nimi, jota
awk käyttää. END määrittää, että seuraava komento suoritetaan vasta,
kun kaikki syöterivit on käsitelty. Toisessa awk-komennon
esimerkissä laskemme ja näytämme tiedoston authors.txt ikien
kumulatiivisen summan ja keskiarvon.
awk '{ tot_age = tot_age + $4 }{ aver=tot_age/NR}{ print $0 " cumulative age sum:" tot_age " average:" aver}' authors.txt
Tässä käytämme automaattista NR-rivimäärämuuttujaa keskiarvon laskemiseen.
Tämä komento tulostaa:
Eeva Pekkanen. Oulu 50 cumulative age sum:50 average:50
Markus Aho. Turku 50 cumulative age sum:100 average:50
Pekka Niemi. Tampere 26 cumulative age sum:126 average:42
Leena Virtanen. Kuopio 32 cumulative age sum:158 average:39.5
sort-komennon käyttö rivien järjestämiseen
Komentoa sort voidaan käyttää tekstitiedoston rivien tai
muun syötedatan järjestämiseen aakkos- tai numerojärjestykseen. sort-komennon
syntaksi on yksinkertainen: sort -options files_to_sort. Oletusarvoisesti
sort järjestää tiedoston rivit aakkosjärjestykseen käyttäen
kirjainkoon huomioivaa lajittelua. Valitsimella -f tehdään
kirjainkoon huomioimaton lajittelu. Jos data sisältää välilyönnillä tai
sarkainmerkillä erotettuja sarakkeita, voit pyytää sort-komentoa käyttämään tiettyä saraketta
(tai sarakkeita) datan järjestämiseen. Käytettävät sarakkeet voidaan
valita valitsimella -k column_number. Esimerkiksi järjestääksemme
tiedoston authors.txt datan (tässä luvussa aiemmin käytetty esimerkkitiedosto)
sukunimien mukaan, jotka sijaitsevat toisessa sarakkeessa, käytä komentoa
joka tulostaa:
Voit myös määrittää muita sarake-erottimia valitsimella -t separator.
Huomaa, että oletusarvoisesti sort järjestää myös numerot
aakkosjärjestykseen. Valitsin -n saa sort-komennon käyttämään sen sijaan
numeerista järjestystä. Valitsin -r kääntää järjestyksen päinvastaiseksi. Numeerinen lajittelu
neljännen sarakkeen mukaan voidaan nyt tehdä komennolla
joka tuottaa
Voit myös määrittää useita sarakkeita käytettäväksi lajittelussa. Esimerkiksi
seuraava komento käyttää neljännen sarakkeen numeerista järjestystä
ensisijaisena lajitteluperusteena (-k4n). Tapauksissa, joissa
useilla riveillä on sama arvo neljännessä sarakkeessa, aakkosjärjestystä
käytetään toissijaisena lajitteluperusteena (-k2):
Tässä tapauksessa tulos on:
Lajiteltu data voidaan tallentaa uuteen tiedostoon joko käyttämällä valitsinta -o
tai uudelleenohjaamalla vakiotuloste tiedostoon merkillä >. Esimerkiksi
molemmat alla olevat komennot luovat saman tiedoston, joka sisältää
tiedoston authors.txt lajitellun version.
Kaksoiskappalerivien poistaminen uniq-komennolla
Komentoa uniq käytetään usein yhdessä
sort-komennon kanssa redundanssin poistamiseen aineistosta. uniq-komento
tarkistaa, ovatko kaksi peräkkäistä riviä syötetiedostossa tai vakiosyötteessä
identtisiä. Oletusarvoisesti uniq poistaa peräkkäiset kaksoiskappalerivit.
Huomaa, että uniq ei tarkista, esiintyykö identtinen rivi muualla
syötteessä. Tämän vuoksi data yleensä lajitellaan ennen
uniq-komennon käyttöä. Esimerkkinä oletetaan, että meillä on tiedosto nimeltä names,
joka sisältää seuraavat rivit:
Komennon
suorittaminen antaa seuraavan tulosteen:
Tulosteessa rivi Leena esiintyy edelleen kahdesti, koska nämä kaksi identtistä
nimeä eivät olleet peräkkäisillä riveillä. Tilanne voidaan korjata
lajittelemalla rivit ennen uniq-komennon käyttöä. Esimerkiksi
tulostaa seuraavan tulosteen
Usein on hyödyllistä tietää, kuinka monta identtistä riviä löytyi. Tämä
tieto voidaan lisätä uniq-komennon tulosteeseen valitsimella -c.
Esimerkiksi
antaa seuraavan tulosteen:
Huomaa, että myös välilyönti- ja sarkainmerkkejä käytetään, kun uniq
vertailee rivejä. Näin ollen rivi, joka sisältää "Leena", ei ole identtinen
rivin kanssa, joka sisältää "Leena ". Oletusarvoisesti uniq erottaa isot ja pienet
kirjaimet, mutta valitsimen -i käyttö saa uniq-komennon ohittamaan kirjainkoon
ja pitämään "leena"- ja "Leena"-rivejä identtisinä. Huomaa kuitenkin, että jos käytät
kirjainkoon huomioimatonta uniq-komentoa, saatat joutua tekemään myös lajittelun
kirjainkoon huomioimattomassa tilassa komennolla sort -f.
Merkkien korvaaminen tr-komennolla
Komentoa tr (translate) käytetään yksittäisten
merkkien korvaamiseen. tr lukee vakiosyötteen ja kirjoittaa muunnetun datan
vakiotulosteeseen. tr-komennon syntaksi on
Esimerkiksi pisteet (.) tiedostossa authors.txt voitaisiin korvata
pilkuilla (,) komennolla
joka tulostaa
Huomaa, että yllä oleva komento ei muuta alkuperäistä syötetiedostoa
millään tavalla. Tässä esitetyissä esimerkeissä tr-komennon tulokset tulostetaan
näytölle. Kun tr:ää käytetään suurten tiedostojen muokkaamiseen, tuloste
tulisi tietenkin ohjata näytön sijasta uuteen tiedostoon. Esimerkiksi
Jos haluat poistaa pisteet, voit käyttää valitsinta -d
vain yhden merkistön kanssa kertomaan, mitkä merkit poistetaan:
Huomaa, että tr muuntaa yksittäisiä merkkejä, ei sanoja. Näin ollen
komento tr "Oulu" "Turku" ei muuttaisi sanaa "Oulu" sanaksi "Turku".
Sen sijaan se tekisi koko tekstiin seuraavat merkkimuunnokset:
O->T, l->r, u->k. tr-komento voi tehdä muunnoksia
erikoismerkeillä, kuten sarkain (\t) ja rivinvaihto (\n), sekä
ennalta määritellyillä merkistöillä, kuten kaikki pienaakkoset ([:lower:]) ja
kaikki suuraakkoset ([:upper:]). Esimerkiksi
korvaisi pisteet rivinvaihdoilla tiedostossa authors.txt:
Tiedoston muokkaaminen niin, että koko teksti kirjoitetaan suuraakkosilla, voidaan tehdä komennolla
joka tuottaa
Katso tr-komennon manuaalisivu (man tr) nähdäksesi luettelon kaikista
erikoismerkeistä ja merkistöistä, joita tr voi käyttää.
Sanojen ja merkkijonojen korvaaminen sed:llä
Merkkijonojen korvaaminen voidaan tehdä sed:llä. sed on virtamuokkain,
jota voidaan käyttää moniin tekstinkäsittelytoimintoihin.
sed lukee merkkijonodataa joko tiedostosta tai toisesta
komennosta putkitettuna, tekee käyttäjän määrittämät muokkaustoiminnot ja
tulostaa sitten muokatun merkkijonon vakiotulosteeseen. sed on erittäin
tehokas työkalu automaattiseen tekstinmuokkaukseen, vaikka sitä onkin hieman vaikea oppia. Tässä
ohjeessa emme anna yleistä johdatusta sed:iin, sillä jo vaatimatonkin
yleiskatsaus veisi useita sivuja. Sen sijaan näytämme muutamia käytännön
esimerkkejä siitä, miten sed:iä voidaan käyttää. sed:iä käytetään yleisesti syntaksilla:
sed_script on tyypillisesti lyhyt muotoilu, joka määrittää, millaista
muokkausta tehdään. Esimerkiksi korvaustoiminnon tekemiseen voisimme
käyttää sed-toimintoa s/"search string"/"replacement string"/g.
Tässä muodossa s tarkoittaa haku- ja korvaustoimintoa.
Lopussa oleva g tarkoittaa, että korvaustoiminto on globaali,
eli kaikki vastaavat merkkijonot korvataan. Voisit korvata esimerkiksi
vain ensimmäisen tai toisen hakumerkkijonon esiintymän rivillä käyttämällä
numeroa 1 tai 2 g:n sijasta. Esimerkiksi toiminto, jossa Oulu korvataan
Turulla tiedostossa authors.txt, voidaan tehdä komennolla
joka tuottaa
Aivan kuten grep-komento, sed tulkitsee annetun hakumerkkijonon
säännöllisenä lausekkeena. Tämä tarkoittaa, että jotkin merkit
tulkitaan erityisiksi säännöllisten lausekkeiden määrittelymerkeiksi. Esimerkiksi
pistettä (.) käytetään määrittämään mikä tahansa yksittäinen merkki. Näin ollen
sed-komento s/"."/","/g ei muuttaisi vain pisteitä vaan kaikki
merkit pilkuiksi (,). Tällaisissa tilanteissa voit käyttää
kenoviivaa (\) kertomaan sed-komennolle, että seuraavaa
merkkiä ei tule tulkita osaksi säännöllistä lauseketta. Toisaalta
säännöllisten lausekkeiden käyttö voi tehdä sed:stä erittäin
tehokkaan. Alla on joitakin säännöllisten lausekkeiden esimerkkejä sovellettuna
authors.txt-tiedostoon sed:llä.
sed-esimerkki 1
Merkin $ käyttö rivin lopun määrittämiseen (huomaa
yksinkertaiset lainausmerkit ('), jotka estävät $-merkkiä tulemasta
tulkituksi bash-muuttujan ilmaisimena):
Tulostaa:
Eeva Pekkanen. Oulu 51 changed
Markus Aho. Turku 51 changed
Pekka Niemi. Tampere 26
Leena Virtanen. Kuopio 32
sed-esimerkki 2
Pisteen (.) käyttö minkä tahansa yksittäisen merkin määrittämiseen:
Tulostaa:
sed-esimerkki 3
Merkin ^ käyttö rivin alun määrittämiseen.
Tulostaa: