programmera.net -> linux -> normal     för utskrift      info@programmera.net

Matchning av textfiler

  Kommando    Exempel  Beskrivning
  cut  cut -d"," -f2 a.txt  Skriver ut det som står mellan första och andra kommatecknet (,) i varje rad i a.txt.
  paste  paste -d"," a.txt b.txt  Lägger ihop varje rad i a.txt med b.txt med ,(komma) som separator och skriver ut.
  join  join a.txt b.txt  Skriver ut föreningen av de rader där första ordet i a.txt matchar första ordet i en rad i b.txt.

På denna sida beskrivs kommandon som matchar rader i en textfil med en annan. Ett gemensamt drag för dessa kommandon är att de inte förändrar den fil de använder sig av, de skriver bara ut något på skärmen. Om du vill spara t. ex. en sorterad fil använder du högerpilen (större än) för att få resultatet att hamna i en ny fil:
[olle@dev1]$ sort a.txt > b.txt
Kommandot ovan sparar den sorterade versonen av a.txt i b.txt.


cut

Flagga  Betydelse  Beskrivning
cut -f1,3 a.txt  field  Skriv ut kolumn 1 och 3 från a.txt.
cut -d"," -f2 a.txt  delimiter  Skriv ut kolumn 2, där kolumnerna separeras av kommatecken.
cut -c1,3 a.txt  char  Skriv ut bokstav nummer 1 och 3 från varje rad i a.txt.
cut -c2-8 a.txt  char  Skriv ut bokstäverna nummer 2 till 8 från varje rad i a.txt.
cut -c17- a.txt  char  Skriv ut bokstäverna från 17 och framåt från a.txt.

Cut skriver ut kolumner från en fil. För att visa hur cut fungerar skapar jag en fil med tab-separerade kolumner:
[olle@dev1]$ cat > d.txt
Adam	Adamson	1945
Björn	Björnsson	1966
Cesar	Cesarsson	1977
Ctrl+d
Nu kan jag t. ex. skriva ut kolumnen innehållande årtal med hjälp av flaggan -f:
[olle@dev1]$ cut -f3 d.txt
1945
1966
1977
Eller flera kolumner:
[olle@dev1]$ cut -f2,3 d.txt
Adamson	1945
Björnsson	1966
Cesarsson	1977
Jag kan skriva ut de 3 första bokstäverna i d.txt med hjälp av flaggan -c:
[olle@dev1]$ cut -c1-3 d.txt
Ada
Bjö
Ces
I filen /etc/passwd använder man kolon för att separera kolumner istället för tab. Om vi vill lista alla användare i systemet använder vi flaggan -d:
[olle@dev1]$ cut -d":" -f1 /etc/passwd
root
bin
...
olle

paste

Flagga  Betydelse  Beskrivning
paste a.txt b.txt     Skriv ut a.txt och b.txt rad för rad separerade av tab.
paste -d"," a.txt b.txt  delimiter  Skriv ut a.txt och b.txt rad för rad separerade av komma.

En ganska enkel variant av att skriva ut flera kolumner från olika filer är paste. Den mer avancerade heter join. Jag börjar med att skapa 2 filer:
[olle@dev1]$ cat > e.txt
a
b
c
Ctrl+d
[olle@dev1]$ cat > f.txt
1
2
3
Ctrl+d
Nu kan jag skriva ut båda filerna enligt:
[olle@dev1]$ paste e.txt f.txt
a	1
b	2
c	3
Eller separerade med t. ex. kommatecken:
[olle@dev1]$ paste -d"," e.txt f.txt
a,1
b,2
c,3

join

Flagga  Betydelse  Beskrivning
join a.txt b.txt     Skriv ut a.txt och b.txt rad för rad där första kolumnen i båda filerna matchar varandra.
join -t':' a.txt b.txt     Som ovan men kolumnerna i a.txt och b.txt är separerade av kolon.
join -a1 a.txt b.txt  add  Skriv ut de matchande raderna plus de rader i a.txt som inte matchar någon rad från b.txt.
join -v1 a.txt b.txt     Skriv ut de rader i a.txt som inte matchar någon rad i b.txt.
join -o 1.2 2.5 a.txt b.txt  output  Skriv ut kolumn 2 från a.txt och kolumn 5 från b.txt från de matchande raderna.
join -1 2 -2 5 a.txt b.txt     Skriv ut de rader där kolumn 2 från a.txt matchar kolumn 5 från b.txt.

Join är en mer avancerad version av paste. För att två filer ska kunna förenas måste båda filerna ha en kolumn som är identisk. Som default är det första kolumnen som är förenings-kolumn. join använder alltså första kolumnen som en nyckel och försöker para ihop rader från de två filerna med matchande nycklar. OBS! Join fungerar bara om de båda filernas förenings-kolumner är sorterade. För att visa hur join fungerar skapar jag 2 filer:
[olle@dev1]$ cat > g.txt
1	Adam
2	Bertil
3	Cesar
4	David
Ctrl+d
[olle@dev1]$ cat > h.txt
1	a
2	b
4	d
7	g
Ctrl+d
Nu kan vi använda join:
[olle@dev1]$ join g.txt h.txt
1	Adam	a
2	Bertil	b
4	David	d
Som synes hoppar join över rad 3 i g.txt eftersom den inte hittar någon match. Om vi skriver h.txt före g.txt i anropet av join blir det lika många matchningar men utskriften blir annorlunda.
[olle@dev1]$ join h.txt g.txt
1	a	Adam
2	b	Bertil
4	d	David
Vad händer om någon fil inte är sorterad? Vi skapar en osorterad fil:
[olle@dev1]$ cat > i.txt
1	a
7	g
2	b
4	d
Nu kommer join att avbrytas då 7 påträffas, eftersom join antar att båda filerna är sorterade:
[olle@dev1]$ join g.txt i.txt
1	Adam	a
Även då båda filerna är sorterade är det inte säkert att man är nöjd med joins beteende. Alla rader där man inte hittar en match kastas ju bort. Man kan behålla de felaktiga raderna från en av filerna med flaggan -a och filens nummer:
[olle@dev1]$ join -a1 g.txt h.txt
1	Adam	a
2	Bertil	b
3	Cesar
4	David	d
-a1 syftar på att de felaktiga raderna från g.txt ska behållas. -a2 betyder att man vill behålla de felaktiga raderna från h.txt. Om man bara vill se vilka rader i g.txt som inte har någon match i h.txt använder man flaggan -v:
[olle@dev1]$ join -v1 g.txt h.txt
3	Cesar
Ibland kanske du inte vill ha med alla kolumner från båda filerna i utskriften. Då använder du flaggan -o. Efter -o kommer en lista med {fil.kolumn} element. Här kommer 2 exempel:
[olle@dev1]$ join -o 1.2 2.2 g.txt h.txt
Adam	a
Bertil	b
David	d
[olle@dev1]$ join -o 2.2 1.2 1.1 g.txt h.txt
a	Adam	1
b	Bertil	2
d	David	4