CSV-gegevens parseren in Bash

CSV-gegevens parseren in Bash
Jane Kelly/Shutterstock.com

Bestanden met door komma’s gescheiden waarden (CSV) zijn een van de meest gebruikte indelingen voor geëxporteerde gegevens. Op Linux kunnen we CSV-bestanden lezen met behulp van Bash-opdrachten. Maar het kan heel ingewikkeld worden, heel snel. We helpen een handje.

Wat is een CSV-bestand?

Een bestand met door komma’s gescheiden waarden is een tekstbestand dat getabelleerde gegevens bevat. CSV is een soort gescheiden gegevens. Zoals de naam al doet vermoeden, een komma “,” wordt gebruikt om elk gegevensveld te scheiden, of waarde– van zijn buren.

Wat is een CSV-bestand en hoe open ik het?

VERWANTWat is een CSV-bestand en hoe open ik het?

CSV is overal. Als een applicatie import- en exportfuncties heeft, ondersteunt deze bijna altijd CSV. CSV-bestanden zijn leesbaar voor mensen. Je kunt er met minder in kijken, ze openen in elke teksteditor en ze van programma naar programma verplaatsen. U kunt bijvoorbeeld de gegevens uit een SQLite-database exporteren en openen in LibreOffice Calc.

Zelfs CSV kan echter ingewikkeld worden. Wilt u een komma in een gegevensveld hebben? Dat veld moet tussen aanhalingstekens staan ​​”"‘ eromheen gewikkeld. Om aanhalingstekens in een veld op te nemen, moet elk aanhalingsteken tweemaal worden ingevoerd.

Als u werkt met CSV dat is gegenereerd door een programma of script dat u hebt geschreven, is de CSV-indeling waarschijnlijk eenvoudig en ongecompliceerd. Als je gedwongen wordt om met complexere CSV-formaten te werken, waarbij Linux Linux is, zijn er ook oplossingen die we daarvoor kunnen gebruiken.

Enkele voorbeeldgegevens

U kunt eenvoudig enkele CSV-voorbeeldgegevens genereren met behulp van sites zoals Online Data Generator. U kunt de gewenste velden definiëren en kiezen hoeveel rijen met gegevens u wilt. Uw gegevens worden gegenereerd met behulp van realistische dummy-waarden en gedownload naar uw computer.

We hebben een bestand gemaakt met 50 rijen dummy-werknemersinformatie:

  • ID kaart: Een eenvoudige unieke integerwaarde.
  • Voornaam: De voornaam van de persoon.
  • achternaam: De achternaam van de persoon.
  • functietitel: De functietitel van de persoon.
  • e-mailadres: Het e-mailadres van de persoon.
  • Afdeling: De bedrijfstak waarin ze werken.
  • staat: De staat waarin het filiaal zich bevindt.

Sommige CSV-bestanden hebben een kopregel met de veldnamen. Ons voorbeeldbestand heeft er een. Dit is de top van ons bestand:

Het voorbeeld CSV-bestand

De eerste regel bevat de veldnamen als door komma’s gescheiden waarden.

Gegevens parseren Vorm het CSV-bestand

Laten we een script schrijven dat het CSV-bestand leest en de velden uit elk record extraheert. Kopieer dit script naar een editor en sla het op in een bestand met de naam “field.sh”.

#! /bin/bash

while IFS="," read -r id firstname lastname jobtitle email branch state
do
  echo "Record ID: $id"
  echo "Firstname: $firstname"
  echo " Lastname: $lastname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(tail -n +2 sample.csv)

Er zit nogal wat in ons kleine script. Laten we het opsplitsen.

Hoe een bestand regel voor regel te verwerken in een Linux Bash-script

VERWANTHoe een bestand regel voor regel te verwerken in een Linux Bash-script

We gebruiken een while lus. Zolang de while lus voorwaarde lost op waar, het lichaam van de while lus wordt uitgevoerd. Het lichaam van de lus is vrij eenvoudig. Een verzameling van echo statements worden gebruikt om de waarden van sommige variabelen naar het terminalvenster af te drukken.

De while lusvoorwaarde is interessanter dan de hoofdtekst van de lus. We specificeren dat een komma moet worden gebruikt als het interne veldscheidingsteken, met de IFS="," uitspraak. De IFS is een omgevingsvariabele. De read commando verwijst naar zijn waarde bij het ontleden van tekstreeksen.

We gebruiken de read commando’s -r (backslashes behouden) optie om eventuele backslashes in de gegevens te negeren. Ze worden behandeld als gewone tekens.

De tekst die de read command parses wordt opgeslagen in een set variabelen genoemd naar de CSV-velden. Ze hadden net zo goed een naam kunnen krijgen field1, field2, ... field7 maar betekenisvolle namen maken het leven gemakkelijker.

De gegevens worden verkregen als de uitvoer van de tail opdracht. We gebruiken tail omdat het ons een eenvoudige manier geeft om de kopregel van het CSV-bestand over te slaan. De -n +2 (regelnummer) optie vertelt tail om te beginnen met lezen bij regel nummer twee.

De <(...) constructie wordt processubstitutie genoemd. Het zorgt ervoor dat Bash de uitvoer van een proces accepteert alsof het afkomstig is van een bestandsdescriptor. Dit wordt dan doorgestuurd naar de while lus, met de tekst die de read opdracht zal ontleden.

Maak het script uitvoerbaar met behulp van de chmod opdracht. U moet dit elke keer doen als u een script uit dit artikel kopieert. Vervang in elk geval de naam van het juiste script.

chmod +x field.sh

Een script uitvoerbaar maken met chmod

Wanneer we het script uitvoeren, worden de records correct opgesplitst in hun samenstellende velden, waarbij elk veld in een andere variabele wordt opgeslagen.

./field.sh

Het CSV-bestand geparseerd door het field.sh-script.

Elk record wordt afgedrukt als een set velden.

Velden selecteren

Misschien willen of hoeven we niet elk veld op te halen. We kunnen een selectie van velden verkrijgen door de cut opdracht.

Dit script heet “select.sh.”

#!/bin/bash

while IFS="," read -r id jobtitle branch state
do
  echo "Record ID: $id"
  echo "Job Title: $jobtitle"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(cut -d "," -f1,4,6,7 sample.csv | tail -n +2)

We hebben de toegevoegd cut opdracht in de procesvervangingsclausule. We gebruiken de -d (scheidingsteken) optie om te vertellen cut komma’s gebruiken “,” als scheidingsteken. De -f (veld) optie vertelt cut we willen velden één, vier, zes en zeven. Die vier velden worden gelezen in vier variabelen, die worden afgedrukt in de hoofdtekst van het while lus.

Dit is wat we krijgen als we het script uitvoeren.

./select.sh

Het CSV-bestand parseren met field.sh om een ​​specifieke selectie van velden te extraheren

Door toevoeging van de cut commando, kunnen we de velden selecteren die we willen en de velden negeren die we niet hebben.

Tot nu toe, zo goed. Maar…

Als de CSV waarmee u te maken heeft ongecompliceerd is zonder komma’s of aanhalingstekens in veldgegevens, zal wat we behandeld hebben waarschijnlijk voldoen aan uw behoeften op het gebied van CSV-parsering. Om de problemen te laten zien die we kunnen tegenkomen, hebben we een kleine steekproef van de gegevens aangepast om er zo uit te zien.

id,firstname,lastname,job-title,email-address,branch,state
1,Rosalyn,Brennan,"Steward, Senior",Rosalyn_Brennan4351@mafthy.com,Minneapolis,Maryland
2,Danny,Redden,"Analyst ""Budget""",Danny_Redden1443@brety.org,Venice,North Carolina
3,Lexi,Roscoe,Pharmacist,,Irlington,Vermont
  • Record één heeft een komma in de job-title veld, dus het veld moet tussen aanhalingstekens worden geplaatst.
  • Record twee heeft een woord tussen twee sets aanhalingstekens in de jobs-title veld.
  • Record drie heeft geen gegevens in de email-address veld.

Deze gegevens zijn opgeslagen als “sample2.csv.” Pas uw “field.sh” -script aan om “sample2.csv” aan te roepen en sla het op als “field2.sh”.

#! /bin/bash

while IFS="," read -r id firstname lastname jobtitle email branch state
do
  echo "Record ID: $id"
  echo "Firstname: $firstname"
  echo " Lastname: $lastname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(tail -n +2 sample2.csv)

Wanneer we dit script uitvoeren, kunnen we scheuren zien verschijnen in onze eenvoudige CSV-parsers.

./field2.sh

Het runnen van het veld2.sh

Het eerste record splitst het functietitelveld op in twee velden, waarbij het tweede deel wordt behandeld als het e-mailadres. Elk veld daarna wordt een plaats naar rechts verschoven. Het laatste veld bevat zowel de branch en de state waarden.

Een record met een veld opgesplitst in twee velden

Het tweede record behoudt alle aanhalingstekens. Het mag slechts één paar aanhalingstekens hebben rond het woord ‘Budget’.

Een record met verkeerd behandelde aanhalingstekens

Het derde record behandelt het ontbrekende veld eigenlijk zoals het hoort. Het e-mailadres ontbreekt, maar verder is alles zoals het hoort.

Een record met een ontbrekend veld, dat correct wordt afgehandeld

Contra-intuïtief is het voor een eenvoudig gegevensformaat erg moeilijk om een ​​robuuste algemene CSV-parser te schrijven. Hulpmiddelen zoals awk zal je dichtbij laten komen, maar er zijn altijd randgevallen en uitzonderingen die er doorheen glippen.

Hoe het awk-commando op Linux te gebruiken

VERWANTHoe het awk-commando op Linux te gebruiken

Proberen een onfeilbare CSV-parser te schrijven is waarschijnlijk niet de beste manier om vooruit te komen. Een alternatieve benadering, vooral als u met een of andere deadline werkt, maakt gebruik van twee verschillende strategieën.

Een daarvan is om een ​​speciaal ontworpen tool te gebruiken om uw gegevens te manipuleren en te extraheren. De tweede is om uw gegevens op te schonen en probleemscenario’s zoals ingesloten komma’s en aanhalingstekens te vervangen. Uw eenvoudige Bash-parsers kunnen dan omgaan met de Bash-vriendelijke CSV.

De csvkit-toolkit

De CSV-toolkit csvkit is een verzameling hulpprogramma’s die speciaal zijn gemaakt om te helpen bij het werken met CSV-bestanden. U moet het op uw computer installeren.

Gebruik deze opdracht om het op Ubuntu te installeren:

sudo apt install csvkit

csvkit installeren op ubuntu

Om het op Fedora te installeren, moet je typen:

sudo dnf install python3-csvkit

csvkit installeren op Fedora

Op Manjaro is het commando:

sudo pacman -S csvkit

csvkit installeren op Manjaro

Als we de naam van een CSV-bestand doorgeven, wordt de csvlook hulpprogramma geeft een tabel weer met de inhoud van elk veld. De veldinhoud wordt weergegeven om te laten zien wat de veldinhoud vertegenwoordigt, niet zoals ze zijn opgeslagen in het CSV-bestand.

Laten we proberen csvlook met ons problematische bestand “sample2.csv”.

csvlook sample2.csv

lastig CSV correct geparseerd door csvlook

Alle velden worden correct weergegeven. Dit bewijst dat het probleem niet de CSV is. Het probleem is dat onze scripts te simplistisch zijn om de CSV correct te interpreteren.

Gebruik de om specifieke kolommen te selecteren csvcut opdracht. De -c (kolom) optie kan worden gebruikt met veldnamen of kolomnummers, of een combinatie van beide.

Stel dat we de voor- en achternaam, functietitels en e-mailadressen uit elke record moeten extraheren, maar we willen de naamvolgorde hebben als ‘achternaam, voornaam’. Het enige wat we hoeven te doen is de veldnamen of nummers in de gewenste volgorde te zetten.

Deze drie commando’s zijn allemaal equivalent.

csvcut -c lastname,firstname,job-title,email-address sample2.csv
csvcut -c lastname,firstname,4,5 sample2.csv
csvcut -c 3,2,4,5 sample2.csv

Velden in een gewenste volgorde kiezen met csvcut

We kunnen de toevoegen csvsort opdracht om de uitvoer op een veld te sorteren. We gebruiken de -c (kolom) optie om de kolom op te geven waarop moet worden gesorteerd, en de -r (omgekeerde) optie om in aflopende volgorde te sorteren.

csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r

Velden kiezen en sorteren op een enkele kolom

Om de uitvoer mooier te maken, kunnen we deze doorvoeren csvlook .

csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r | csvlook

csvlook gebruiken om de gesorteerde selectie van velden mooi af te drukken

Een leuke bijkomstigheid is dat, ook al zijn de records gesorteerd, de kopregel met de veldnamen als eerste regel behouden blijft. Zodra we tevreden zijn dat we de gegevens hebben zoals we het willen, kunnen we de csvlook vanuit de opdrachtketen en maak een nieuw CSV-bestand door de uitvoer om te leiden naar een bestand.

We hebben meer gegevens toegevoegd aan het “sample2.file”, het verwijderd csvsort opdracht en maakte een nieuw bestand met de naam “sample3.csv.”

csvcut -c 3,2,4,5 sample2.csv > sample3.csv

Een veilige manier om CSV-gegevens op te schonen

Als u een CSV-bestand opent in LibreOffice Calc, wordt elk veld in een cel geplaatst. U kunt de zoek- en vervangfunctie gebruiken om naar komma’s te zoeken. U kunt ze vervangen door ‘niets’ zodat ze verdwijnen, of door een teken dat geen invloed heeft op de CSV-parsering, zoals een puntkomma ‘;” bijvoorbeeld.

U ziet de aanhalingstekens rond geciteerde velden niet. De enige aanhalingstekens die u ziet, zijn de ingesloten aanhalingstekens binnenkant veld gegevens. Deze worden weergegeven als enkele aanhalingstekens. Deze zoeken en vervangen door een enkele apostrof “'” vervangt de dubbele aanhalingstekens in het CSV-bestand.

Zoeken en vervangen van LibreOffice Calc gebruiken om aanhalingstekens te vervangen door apostrofs

Zoeken en vervangen in een toepassing zoals LibreOffice Calc betekent dat u niet per ongeluk een van de komma’s voor het scheiden van velden kunt verwijderen, noch de aanhalingstekens rond velden tussen aanhalingstekens kunt verwijderen. Je verandert alleen de gegevens waarden van velden.

We hebben alle komma’s in velden met puntkomma’s en alle ingesloten aanhalingstekens met apostrofs gewijzigd en onze wijzigingen opgeslagen.

Het gewijzigde CSV-bestand

Vervolgens hebben we een script gemaakt met de naam “field3.sh” om “sample3.csv” te ontleden.

#! /bin/bash

while IFS="," read -r lastname firstname jobtitle email
do
  echo " Lastname: $lastname"
  echo "Firstname: $firstname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo ""
done < <(tail -n +2 sample3.csv)

Laten we eens kijken wat we krijgen als we het uitvoeren.

./field3.sh

Een gedeelte van correct geparseerde CSV

Onze eenvoudige parser kan nu onze eerder problematische records aan.

Je zult veel CSV zien

CSV komt misschien wel het dichtst in de buurt van een gemeenschappelijke taal voor applicatiegegevens. De meeste toepassingen die een bepaalde vorm van gegevens verwerken, ondersteunen het importeren en exporteren van CSV. Als u weet hoe u op een realistische en praktische manier met CSV om moet gaan, komt u goed van pas.

Nieuwste artikelen

spot_img

Related Stories

Leave A Reply

Vul alstublieft uw commentaar in!
Vul hier uw naam in