Tapaaminen 13.01.2011

Kohteesta Turuxi
Loikkaa: valikkoon, hakuun
Paikka
Näillä näkymin Turku-salissa.
Aika
Kello 18 alkaen

Tapaamme taas tammikuun toisena torstaina Turku-salissa. Tapaamisen teemana "näppärät komentorivityökalut". Tarkoituksena on, että osallistujat voivat esitellä käteviksi kokemiaan komentorivityökaluja ja "one-linereita". Esimerkkeinä mainittakoon: bashin for- ja while-silmukat, sort, uniq, seq, sed, bashin "string matching" ominaisuudet, jne.

Tervetuloa!

Tapaamisessa keskusteltua

Tapaamisessa keskusteltiin muun muassa komentorivityökaluista, joiden toiminnasta alla lyhyt yhteenveto.

wget

Komentoriviohjelma, jolla voi ladata verkosta yksittäisiä sivuja/tiedostoja tai kokonaisia sivustoja.

wget http://turuxi.org/images/b/b5/Turuxi-banner.svg

sort

Komentoriviohjelma, joka järjestää standardi-inputista saamansa tekstirivit aakkosjärjestykseen. Valitsimella -n järjestetään numeraaliseen järjestykseen.

cat tiedosto.txt | sort

uniq

Komentoriviohjelma, joka poistaa standardi-inputista saamastaan tekstistä peräkkäisistä samanlaisista riveistä toistot ja jättää jäljelle vain yhden. Yleensä hyödyllinen yhdessä sort-ohjelman kanssa.

cat tiedosto.txt | sort | uniq

sed

Stream editor, eli komentoriviohjelma, jolla voi monipuolisesti käsitellä standardi-inputin kautta saatua tekstiä. Eräs yleinen käyttö sed-ohjelmalle on säännöllisillä lausekkeilla (regexp) löydettyjen tekstien korvaaminen.

cat tiedosto |  sed s/bar/BAR/g

seq

Komentoriviohjelma, joka tuottaa luettelon lukuja, yhden per rivi. Käytännöllinen esim. for-silmukan yhteydessä. Yhdellä parametrilla luettelo alkaa luvusta 1 ja jatkuu parametrina annettuun saakka.

seq 7
1
2
3
4
5
6
7

Kahdella parametrilla ensimmäinen on aloitusluku ja toinen lopetusluku.

seq 7
3
4
5
6
7

Kolmella parametrilla ensimmäinen on aloitusluku, toinen askelen suuruus ja kolmas lopetusluku.

seq 3 2 17
3
5
7
9
11
13
15
17

Askel voi olla myös alas päin ja muutakin kuin kokonaisluku.

seq 3 -0.5 -2
3.0
2.5
2.0
1.5
1.0
0.5
0.0
-0.5
-1.0
-1.5
-2.0

Lisävalitsin -w lisää kaikkiin lukuihin etunollia niin, että ne ovat kaikki pituudeltaan yhtä pitkiä.

seq -w 1 45 200
001
046
091
136
181

bash

Yllä olevia komentoja voi käyttää helposti bash-komentorivin omien komentojen ja ohjelmointikielen rakenteiden kanssa.

for-silmukka

Bashin for-silmukka on muotoa:

for i in lista sanoja jotka muuttuja käy läpi; do echo "Komennot, jotka suoritetaan kullakin muuttujan arvolla"; echo "i = $i"; done
Komennot, jotka suoritetaan kullakin muuttujan arvolla
i = lista
Komennot, jotka suoritetaan kullakin muuttujan arvolla
i = sanoja
Komennot, jotka suoritetaan kullakin muuttujan arvolla
i = jotka
Komennot, jotka suoritetaan kullakin muuttujan arvolla
i = muuttuja
Komennot, jotka suoritetaan kullakin muuttujan arvolla
i = käy
Komennot, jotka suoritetaan kullakin muuttujan arvolla
i = läpi

For-silmukka on kätevää yhdistää esimerkiksi wget- ja seq-ohjelmien kanssa:

for i in `seq -w 5 12`; do wget http://osoite.com/tiedosto-$i.txt ; done

Yllä oleva komentorivi hakee palvelimelta osoite.com tiedostot:

tiedosto-05.txt
tiedosto-06.txt
tiedosto-07.txt
tiedosto-08.txt
tiedosto-09.txt
tiedosto-10.txt
tiedosto-11.txt
tiedosto-12.txt

while-silmukka

Bashin while-silmukkaa suoritetaan niin kauan kuin sen ehtona oleva komento tai ohjelma suoritetaan onnistuneesti. Komentona voidaan käyttää esimerkiksi read i-komentoa, joka lukee standardi-inputista yhden rivin ja sijoittaa sen sisällön muuttujaan i. Esimerkiksi:

while read i; do echo "Tekstirivi: $i"; done < tiedosto.txt

Yllä oleva silmukka saa standardi-inputiin tiedosto.txt:n sisällön (< tiedosto.txt), komento read i lukee kunkin rivin yksi kerrallaan ja sijoittaa muuttujaan i. While-silmukka suorittaa silmukkaa niin kauan kunnes read-komento lukee tiedoston loppumerkin (^d, eli ctrl-d).

muuttujat

Bashin muuttujien sisältöä voidaan muuntaa seuraavilla operaatioilla:

nimi=tiedosto.nimi.txt
echo ${nimi##*.}
txt

Yllä olevassa muuttujan nimi sisällöstä etsitään vasemmalta mahdollisimman pitkä kaavaan *. sopiva osuus ja poistetaan se. Tässä tapauksessa poistettava osuus on tiedosto.nimi.

nimi=tiedosto.nimi.txt
echo ${nimi#*.}
nimi.txt

Tässä esimerkissä taas samasta muuttujasta nimi etsitään vasemmalta mahdollisimman lyhyt kaavaan *. sopiva osuus ja poistetaan se. Tässä tapauksessa osuus on tiedosto.

nimi=tiedosto.nimi.txt
${nimi%%.*}
tiedosto

Tässä taas kaavaan sovitetaan mahdollisimman pitkää osuutta, mutta oikealta. Sopiva osuus on .nimi.txt

nimi=tiedosto.nimi.txt
${nimi%.*}
tiedosto.nimi

Neljännessä esimerkissä taas muuttujasta haetaan oikealta päin mahdollisimman lyhyt sopiva osuus .txt. Muistisääntönä voidaan käyttää sitä, että muuttujaa symboloiva merkki $ saadaan näppäimistöltä näppäimestä 4, vasemmalta kaavaa etsivää toimintoa symboloiva # saadaan sen vasemmalla puolella olevasta näppäimestä 3 ja oikealta kaavaa etsivää toimintoa symboloiva % taas oikealta puolelta näppäimestä 5. Pitkää osumaa etsitään pitkillä merkinnöillä ## ja %%, lyhyttä osumaa lyhyillä # ja %.

Suoraan jonkin osuuden muuttujan sisällöstä saa lohkottua kertomalla aloitusmerkin indeksi ja halutun osuuden pituus. Indeksointi alkaa luvusta 0.

nimi=tiedosto.nimi.txt
${nimi:3:8}
dosto.ni

Hakemiston vaihto

Tuttujen hakemistoa vaihtavien komentojen cd, cd ~, cd .. jne. lisäksi on muutama harvemmin muistettu.

pesasa@lynx:~$ cd /usr/share/doc
pesasa@lynx:/usr/share/doc$ cd -
/home/pesasa
pesasa@lynx:~$ cd -
/usr/share/doc
pesasa@lynx:/usr/share/doc$

Komennolla cd - voidaan siis siirtyä edelliseen käytössä olleeseen hakemistoon. Toistettuna sama komento palauttaa taas takaisin, eli voidaan vaihdella kahden hakemiston välillä.

Useamman hakemiston muistamiseen voidaan käyttää hakemistopinoa. Komennolla pushd voidaan siirtyä uuteen hakemistoon ja laittaa samalla vanha hakemisto pinoon. Komennolla popd voidaan taas palata takaisin pinon päälimmäiseen hakemistoon.

pesasa@lynx:~$ pushd /usr/share/doc
/usr/share/doc ~
pesasa@lynx:/usr/share/doc$ pushd /etc
/etc /usr/share/doc ~
pesasa@lynx:/etc$ pushd /usr
/usr /etc /usr/share/doc ~
pesasa@lynx:/usr$ popd
/etc /usr/share/doc ~
pesasa@lynx:/etc$ popd
/usr/share/doc ~
pesasa@lynx:/usr/share/doc$ popd
~
pesasa@lynx:~$