I denna artikel kommer vi att gå igenom hur man använder verktygen tr, sed och awk för att modifiera en text. Den kommer att vara helt och hållet baserat på exempel. Uppgiften kommer vara att snygga till en lista över Robert De Niro-filmer.

Börja med att ladda hem listan till din dator. Det är en CSV fil och ser ut som nedan (de sista raderna):

2013,  11, "Killing Season"
2014,   9, "The Bag Man"
2015,  60, "Joy"
2015,  26, "Heist"
2015,  61, "The Intern"
2016,  11, "Dirty Grandpa"

Det vi ska åstadkomma är att ändra utseendet på listan så att den istället ser ut så här:

Killing Season - 2013
The Bag Man - 2014
Joy - 2015
Heist - 2015
The Intern - 2015
Dirty Grandpa - 2016

Det vill säga filmens namn ska stå först, sedan årtalet separerat med ett bindestreck. Vi ska också plocka bort alla citattecken och Rotten Tomatoes-poängen.

tr

Det första verktyget vi kommer att använda här är tr (för translate). Detta är ett verktyg för att byta ut specifika tecken mot andra tecken, eller helt enkelt för att ta bort tecken som vi ska göra i vårt fall.

För att byta ut tecken (eller översätta), används tr på följande sätt:

$> echo "kalle" | tr 'a' '4'
k4lle

Här översatte vi a mot 4. Detta går även att översätta flera tecken samtidigt. Låt oss säga att vi vill översätta a mot 4, e mot 3 och l mot |. Då gör vi följande vis:

$> echo "kalle" | tr 'ael' '43|'
k4||3

För att ta bort tecken används flaggan -d.

$> echo "kalle" | tr -d 'e'
kall

Nu när vi vet hur tr fungerar kan vi testa att ta bort alla citattecken ur listan.

ANNONS FÖR VÅRA EGNA BÖCKER Demonerna på internet

$> cat deniro.csv | tr -d '"'
2013,  11, Killing Season
2014,   9, The Bag Man
2015,  60, Joy
2015,  26, Heist
2015,  61, The Intern
2016,  11, Dirty Grandpa

awk

awk är ett verktyg och programspråk för att söka i och behandla texter. Här kommer vi att använda awk för att välja ut de fält vi är intresserade av i listan. Men först ett exempel på hur awk används. Vi kommer här att använda /etc/passwd-filen som exempel.

De fem sista raderna i min /etc/passwd-fil ser ut som nedan. Här använder jag tail för att visa de fem sista raderna.

$> tail -n 5 /etc/passwd
sddm:x:123:129:Simple Desktop Display Manager:/var/lib/sddm:/bin/false
anna:x:1006:1007:Anna,,,:/home/anna:/bin/bash
fnatte:x:1007:1008::/home/fnatte:/bin/bash
nut:x:124:130::/var/lib/nut:/bin/false
pulse:x:112:118:PulseAudio daemon,,,:/var/run/pulse:/bin/false

Fälten i passwd-filen är åtskilda med ett kolon. Låt oss nu anta att vi endast är intresserade av användarnamnet och hemkatalogen. Dessa är fält nummer 1 och 6. Det är nu awk kommer in i bilden.

$> tail -n 5 /etc/passwd | awk -F ":" '{ print $1, $6 }'
sddm /var/lib/sddm
anna /home/anna
fnatte /home/fnatte
nut /var/lib/nut
pulse /var/run/pulse

Vi specificerade fältseparatorn med -F ":". Anges ingen fältseparator antas att blanksteg separerar fälten.

Nu när vi vet hur awk fungerar kan vi använda det för att välja ut filmens namn och årtal från listan med De Niro-filmer. Årtalet är fält nummer 1, och filmen är fält nummer 3. Här kommer vi således att skriva ut fält 3 före fält 1, och mellan dem ska vi skriva ut ett bindestreck. Här måste vi också använda en annan fältseparator. I listan används kommatecken för att separera fälten, så vi anger detta med -F ",". Nu lägger vi till awk efter tr med ännu en rörledning.

$> cat deniro.csv | tr -d '"' | awk -F "," '{ print $3, "-", $1 }'
 Killing Season - 2013
 The Bag Man - 2014
 Joy - 2015
 Heist - 2015
 The Intern - 2015
 Dirty Grandpa - 2016

Perfekt, bortsett från att det finns ett blanksteg framför varje rad. För att få bort det kan vi använda sed.

sed

sed är istället ett verktyg för att redigera texter. Redigeringarna görs med reguljära uttryck, så här får vi nytta av det vi lärt oss från Reguljära uttryck, del 1 och Reguljära uttryck, del 2.

Här ska vi ta bort ett mellanslag som står som allra första tecken på varje rad. Som vi kommer ihåg från artiklarna om reguljära uttryck markeras början på en rad med ^.

Med sed kommer vi att använda funktionen s för substitute. När vi skriver reguljära uttryck för verktyg som sed och vi (och även för PHP) skrivs dessa mellan två styck / för att avgränsa uttrycket. Efter det sista snedstrecket skriver man det som ska ersätta matchningen av det reguljära uttrycket.

Om vi återigen använder /etc/passwd-filen som exempel kan vi nu ersätta alla kolon med understreck.

$> tail -n 5 /etc/passwd | sed 's/:/_/g'
sddm_x_123_129_Simple Desktop Display Manager_/var/lib/sddm_/bin/false
anna_x_1006_1007_Anna,,,_/home/anna_/bin/bash
fnatte_x_1007_1008__/home/fnatte_/bin/bash
nut_x_124_130__/var/lib/nut_/bin/false
pulse_x_112_118_PulseAudio daemon,,,_/var/run/pulse_/bin/false

s står alltså för substitue. Därefter kommer det reguljära uttrycket mellan två snedstreck; i det här fallet är det bara ett kolon /:/. Därefter kommer understrecket som ska används istället för kolonet. Därefter avslutas hela uttrycket med ett sista snedstreck. Det sista tecknet, g, betyder global. Om vi utelämnar g kommer bara det första kolonet på varje rad att bytas ut mot understreck.

Nu när vi vet hur sed fungerar lägger vi till det i slutet av våra andra kommandon med en ny rörledning. Eftersom vi här ska ta bort mellanslaget lämnar vi ersättningen tom.

$> cat deniro.csv | tr -d '"' | awk -F "," '{ print $3, "-", $1 }' | sed 's/^ //'
Killing Season - 2013
The Bag Man - 2014
Joy - 2015
Heist - 2015
The Intern - 2015
Dirty Grandpa - 2016

Och det hela fungerar perfekt! Vi har nu formaterat listan precis så som vi vill.

Textbearbetning har alltid varit en väsentlig del av UNIX – ända sedan AT&T Bell Labs tid. För den som är intresserad av historia rekommenderar jag följande två YouTube-klipp: