GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So analysieren Sie CSV-Dateien in Bash-Skripten unter Linux

Komma-getrennte Werte auch bekannt als CSV sind halbstrukturierte Daten, die ein Komma als Trennzeichen verwenden, um die Wörter zu trennen. CSV-Dateiformate sind bei Datenprofis sehr beliebt, da sie mit vielen CSV-Dateien umgehen und diese verarbeiten müssen, um Erkenntnisse zu gewinnen. In diesem Artikel konzentrieren wir uns darauf, wie CSV-Dateien in Bash-Shell-Skripten unter Linux geparst werden.

In den meisten Teilen dieses Artikels werde ich awk verwenden und sed Tools für das CSV-Parsing, anstatt verschiedene Befehle wie grep , cut , tr usw.

Das awk Dienstprogramm reduziert die Komplexität der Weiterleitung mehrerer Befehle oder das Schreiben einer Schleife mit Logik, um die Daten zu erfassen. Stattdessen können Sie einen Einzeiler-Code in awk schreiben um die Arbeit zu erledigen.

1. CSV-Datei zur Verarbeitung vorbereiten

Ihre CSV-Datei wurde möglicherweise aus einer Datenbank oder einer API generiert, oder Sie haben möglicherweise einige Befehle ausgeführt und die Ausgabe in das Trennzeichen im CSV-Format konvertiert. In jedem Fall müssen Sie zuerst den Datensatz analysieren, bevor Sie Ihre Logik darauf anwenden.

Als Best Practice sollten Sie Ihren Datensatz bereinigen, bevor Sie ihn verwenden. Warum sollten wir den Datensatz bereinigen? Es kann Situationen geben, in denen es leere Zellenwerte oder keine ordnungsgemäße Formatierung in Kopfzeilen, zusätzliche Spalten gibt, die für die Verarbeitung nicht erforderlich sind, und vieles mehr.

Ich verwende die folgenden CSV-Daten, die ich von Kaggle abgerufen habe zu Demonstrationszwecken.

Player_Id,Player_Name,DOB,Batting_Hand,Bowling_Skill,Country
1,SC Ganguly,8-Jul-72,Left_Hand,Right-arm medium,
2,BB McCullum,27-Sep-81,Right_Hand,Right-arm medium,
3,RT Ponting,19-Dec-74,Right_Hand,Right-arm medium,
4,DJ Hussey,15-Jul-77,Right_Hand,Right-arm offbreak,Australia
5,Mohammad Hafeez,17-Oct-80,,Right-arm offbreak,Pakistan
6,R Dravid,11-Jan-73,,Right-arm offbreak,India
7,W Jaffer,16-Feb-78,,Right-arm offbreak,India
8,V Kohli,5-Nov-88,,Right-arm medium,India
9,JH Kallis,16-Oct-75,,Right-arm fast-medium,South Africa
10,CL White,18-Aug-83,Right_Hand,Legbreak googly,Australia
11,MV Boucher,3-Dec-76,Right_Hand,Right-arm medium,South Africa
12,B Akhil,7-Oct-77,Right_Hand,Right-arm medium-fast,India
13,AA Noffke,30-Apr-77,Right_Hand,Right-arm fast-medium,Australia
14,P Kumar,2-Oct-86,Right_Hand,Right-arm medium,India
15,Z Khan,7-Oct-78,Right_Hand,Left-arm fast-medium,India

1.1. Leere Zellen ersetzen

In einigen Fällen enthält die CSV-Datei keine Werte in bestimmten Zellen. Sehen Sie sich den folgenden Screenshot an, wo einige leere Zellen zwischen den Spalten sind.

Ich würde es immer durch "NA" oder "Kein Wert" ersetzen, damit es keine leeren Zellen gibt. Sie können das folgende awk verwenden Snippet, um jede leere Zelle durch Ihren gewünschten Wert zu ersetzen. In diesem Fall ersetze ich die leeren Zellen durch "Kein Wert".

awk 'BEGIN{FS=",";OFS=","}
    {
      for(i=1;i<=NF;i++)
      {
        if($i == ""){
         $i="No Value"
        }
      }
      print
    }' ~/Downloads/Player.csv > player_cleaned.csv

Dieses Snippet funktioniert so, dass ich das Feldtrennzeichen und das Ausgabefeldtrennzeichen auf Komma setze (FS=",";OFS="," ). Verwendung von for loop , durch jede Zelle in einer Zeile iterieren, und wenn eine Zelle leer ist ($i == "" ) und ersetzen Sie es dann durch "No value" ($i="No value" ). Sie müssen die Änderungen in eine neue Datei umleiten.

Empfohlene Lektüre:

  • Bash-Umleitung mit Beispielen erklärt

1.2. Den Header groß schreiben

CSV-Dateien können Kopfzeilen haben oder auch nicht. Aber wenn es eine Überschrift gibt, würde ich sie immer groß schreiben, um die Lesbarkeit zu verbessern. Das geht ganz einfach mit awk oder sed . Ich werde Ihnen beide Wege zeigen.

awk 'BEGIN{FS=",";OFS=","}
    {
        if(NR==1){
            print toupper($0)
        } else {
            print
        }
    }' player.csv > player_cleaned.csv

Hier prüfen wir, ob die Zeile die erste Zeile ist, indem wir (NR==1 ) und mit toupper() Funktion, um es zu kapitalisieren. Dasselbe Snippet kann als Einzeiler geschrieben werden.

awk 'NR==1{ print toupper($0) }NR>1' player.csv > player_cleaned.csv

Mit awk , müssen Sie die Änderungen erneut in eine neue Datei umleiten. Stattdessen können Sie 'sed verwenden ', um die Änderungen direkt in der Datei zu ändern. Hier \U wandelt die Groß-/Kleinschreibung in Großbuchstaben um. Wenn Sie eine Umwandlung in Kleinbuchstaben vornehmen möchten, verwenden Sie \L .

$ sed -i -e '1 s/(.*)/\U\1/' player_cleaned.csv
$ cat player_cleaned.csv

1.3. Nachgestelltes Komma entfernen

Ihre CSV-Datei kann am Ende ein Komma haben. Um die nachgestellten Kommas zu löschen, können Sie die folgende Methode befolgen.

Ab Zeile 7 habe ich absichtlich ein nachgestelltes Komma hinzugefügt bis 11 in meiner Datendatei.

Um alle nachgestellten Kommas zu entfernen, führen Sie den folgenden sed aus Befehl:

$ sed -i 's/,$//' ~/Documents/player_cleaned.csv

Jetzt sind wir mit dem Reinigungsteil fertig. Möglicherweise sind für Sie einige weitere Schritte erforderlich, aber das hängt davon ab, wie Ihre CSV-Datei strukturiert ist und was bereinigt werden muss.

2. Pretty Print CSV-Datei im Terminal

Wenn Sie versuchen, die CSV-Dateien im Terminal anzuzeigen, gibt es einige Optionen, mit denen Sie die Datei im Tabellenformat drucken können, um die Lesbarkeit zu verbessern.

2.1. Spaltenbefehl

Der erste Ansatz besteht darin, die column zu verwenden Befehl. Der Spaltenbefehl akzeptiert ein Trennzeichen, das auf Komma gesetzt ist, und ein Trennzeichen, um die Spalte zu teilen, die im folgenden Befehl auf Tabulator gesetzt ist. Sie können auch Ihre eigenen benutzerdefinierten Trennzeichen festlegen.

$ cat player_cleaned.csv | column -s, -t
$ column -s, -t player_cleaned.csv

2.2. CSV-Look-Befehl

Csvlook ist ein Dienstprogramm, das mit dem csvkit-Paket geliefert wird. Es ist nicht nötig, ein Trennzeichen zu setzen, wie wir es bei der column getan haben Befehl.

$ cat player_cleaned.csv | csvlook
$ csvlook player_cleaned.csv

2.3. Python Pretty Table

Wenn Sie die Python-Datei prettytable haben Wenn das Modul installiert ist, können Sie den folgenden Einzeiler ausführen und die CSV-Datei umleiten, um die Tabelle zu generieren.

python -c "import sys,prettytable; print(prettytable.from_csv(sys.stdin))" < player_cleaned.csv

Sie können auch einen Alias erstellen für den Einzeiler und übergeben Sie den Dateinamen als Argument.

$ alias ptable='python -c "import sys,prettytable; print(prettytable.from_csv(sys.stdin))"'
$ ptable < player_cleaned.csv

3. Abrufen von Daten aus einer CSV-Datei

3.1. Zeilen- und Spaltenanzahl drucken

Führen Sie den folgenden Befehl aus, um die Anzahl der Spalten in der CSV-Datei abzurufen. Hier die Variable NF steht für die Anzahl der Felder, getrennt durch ein Komma als Trennzeichen.

$ awk -F, 'END{print NF}' player_cleaned.csv
6

Führen Sie den folgenden Befehl aus, um die Anzahl der Zeilen abzurufen. Hier die Variable NR stellt den aktuellen Datensatz dar (d. h. jede Zeile wird als ein Datensatz betrachtet).

$ awk -F, 'END{print NR}' player_cleaned.csv
16

Führen Sie den folgenden Befehl aus, um die erste Zeile (Kopfzeile) zu überspringen und die Anzahl der Zeilen zu berechnen.

$ awk -F, 'END{print NR-1}' player_cleaned.csv
15

3.2. Gesamte CSV-Datei drucken

Das ist ziemlich einfach. Sie können cat verwenden oder awk um die gesamte CSV-Datei zu drucken.

$ cat player_cleaned.csv
$ awk '{print}' player_cleaned.csv

3.3. Nur Kopfzeile aus CSV-Datei drucken

Wenn Sie nur die Kopfzeile drucken, erhalten Sie einen guten Überblick darüber, welche Art von Daten Ihre CSV-Datei enthält. Sie können den head verwenden oder awk Befehl, nur den Header abzurufen.

$ head -n 1 player_cleaned.csv
$ awk 'NR==1' player_cleaned.csv

PLAYER_ID,PLAYER_NAME,DOB,BATTING HAND,BOWLING SKILL,COUNTRY

3.4. Kopfzeile ausschließen

Um die Kopfzeile auszuschließen und alle anderen Zeilen zu drucken, verwenden Sie den awk Befehl. Die awk-Variable NR > 1 wird die erste Zeile übersprungen.

$ awk '(NR>1)' player_cleansed.csv

Sed kann auch verwendet werden, um die erste Zeile auszuschließen und alle anderen Zeilen zu drucken. Der 1d flag löscht die erste Zeile und gibt alle anderen Zeilen auf stdout (Terminal) aus.

$ sed 1d < player_cleaned.csv

3.5. Einzelne Spalten drucken

Wir können die Spaltenposition verwenden, um die gesamte Spalte zu drucken. Um dies zu erreichen, gibt es zwei Ansätze. Der erste Ansatz wird die Verwendung von awk sein und der zweite Ansatz wird die Verwendung von Schleifen sein . Awk wird viel einfacher sein, die Spalte zu greifen.

Awk teilt die Zeile standardmäßig basierend auf dem Trennzeichen und speichert die Werte in $1 , $2 , $3 usw. Das Standardtrennzeichen für awk ist Leerzeichen .

Sehen Sie sich das folgende Snippet an, in dem das Feldtrennzeichen (FS="," ) und Ausgabefeldtrennzeichen (OFS="," ) wird auf Komma gesetzt. Die print-Anweisung druckt die erste Spalte, zweite Spalte und sechste Spalte.

awk 'BEGIN{FS=",";OFS=","}
    {
        print $1,$2,$6
    }' player_cleansed.csv

Sie können das obige Snippet auch in einem Einzeiler schreiben.

awk 'BEGIN{FS=",";OFS=","}{print $1,$2,$6}' player_cleansed.csv

Nun wäre der zweite Ansatz Schleifen zu verwenden.

IFS="," 
while read -r -a fields
do
    echo ${fields[0]},${fields[1]},${fields[5]}
done < player_cleaned.csv

Lassen Sie mich erklären, was genau passiert, wenn Sie das obige Snippet ausführen.

  • Wir setzen das interne Feldtrennzeichen IFS auf Komma.
  • Mit dem read-Befehl erstellen wir ein Array namens "fields" und leiten die Eingabedatei an die while loop um .
  • Bei jeder Iteration wird Zeile für Zeile gelesen und die Zeile als Array-Elemente in "Feldern" gespeichert, sodass Sie die Indexposition des Arrays verwenden können, um nur die jeweilige Spalte zu erfassen.

Hinweis: Der Indexwert beginnt bei 0..N

3.6. Zeile drucken, die der Bedingung entspricht

Wenn Sie die Zeilen drucken möchten, die einer bestimmten Bedingung entsprechen, können Sie dies einfach mit awk tun . Gehen wir einige Szenarien durch.

Führen Sie den folgenden Befehl aus, um alle Zeilen zu drucken, die mit einem Wert in einer Spalte übereinstimmen. Hier versuche ich, alle Zeilen zu drucken, die mit dem Wert "Indien" in Spalte 6 übereinstimmen.

$ awk -F , '$6 == "India"' player_cleaned.csv

Führen Sie den folgenden Befehl aus, um alle Zeilen zu drucken, die nicht mit einem bestimmten Wert übereinstimmen. Anstelle eines Gleichheitsoperators verwenden wir den Ungleich-Operator .

$ awk -F , '$6 != "India"' player_cleaned.csv

Sie können auch eine Bedingungsprüfung für mehr als eine Spalte durchführen, indem Sie den logischen UND- und den logischen ODER-Operator verwenden. Angenommen, ich möchte alle Zeilen überprüfen, in denen das Land „India“ und die Schlaghand „Right_hand“ ist.

Hier, $4 zeigt auf die 4. Spalte und $6 zeigt auf die 6. Spalte. Das Symbol && wird als logischer UND-Operator verwendet, um zwei Bedingungen auszuwerten.

$ awk -F , '$4 == "Right_Hand" && $6 == "India"' player_cleaned.csv

Wenn Sie den Header zusammen mit dem Ergebnis der bedingten Prüfung einschließen möchten, verwenden Sie den folgenden Befehl. Zuerst drucke ich die erste Zeile mit NR==1 , und verwenden Sie dann den logischen UND-Operator, der die Bedingungsprüfung ausführt, um die Ergebnisse zu drucken.

$ awk 'NR==1' player_cleaned.csv && awk -F , '$4 == "Right_Hand" && $6 == "India"' player_cleaned.csv

Wenn Sie die Ausgabe drucken oder umleiten möchten, führen Sie den gesamten Befehl in einer Subshell aus, indem Sie ihn in Klammern einschließen .

$ (awk 'NR==1' player_cleaned.csv && awk -F , '$4 == "Right_Hand" && $6 == "India"' player_cleaned.csv) | column -t -s,

Ein Hinweis zu Csvkit

Was wir bisher in diesem Artikel gesehen haben, ist einfach und unkompliziert. Aber wenn Ihre CSV-Datei eine komplexe Struktur hat, wird es mühsam, sie mit dem obigen Ansatz zu analysieren. Es gibt ein Dienstprogramm namens CSVKIT , ein hervorragendes Dienstprogramm zum Arbeiten mit CSV-Dateien in Bash.

Das Problem mit dem csvkit-Dienstprogramm ist, dass es standardmäßig in Ihrer Distribution installiert ist und Sie es möglicherweise manuell installieren müssen. In Ihrer Unternehmensumgebung ist dies möglicherweise nicht möglich, da es einige Einschränkungen bei der Installation externer Pakete geben kann. Aber dieses Dienstprogramm ist erwähnenswert und wir werden einen separaten ausführlichen Artikel dafür erstellen.

Schlussfolgerung

In diesem Handbuch haben wir gesehen, wie Sie mit CSV-Dateien mit awk, sed arbeiten. Sie können auch andere Dienstprogramme wie cut, grep, tr usw. verwenden, um das gewünschte Ergebnis zu erzielen, aber awk und sed machen Ihr Leben einfacher und reduzieren die Komplexität des Schreibens vieler Codes. Wenn Sie Feedback haben, erwähnen Sie es im Kommentarbereich und wir freuen uns, es von Ihnen zu hören.

Ähnliches Lesen:

  • Bash-Skripting – Analysieren Sie Argumente in Bash-Skripten mithilfe von getopts
  • So analysieren und verschönern Sie JSON mit Linux-Befehlszeilentools

Linux
  1. So benennen Sie Dateien unter Linux um

  2. Wie kürze ich die Bash-Eingabeaufforderung unter Linux?

  3. So komprimieren Sie mehrere Dateien unter Linux

  4. Wie die BASH-Shell ihre Konfigurationsdateien unter Linux lädt

  5. Wie parse ich eine CSV-Datei in Bash?

So benennen Sie Dateien und Verzeichnisse in Linux um

So benennen Sie eine Datei (en) in Linux um

So debuggen Sie Bash-Skripte in Linux und Unix

Shell-Scripting für Anfänger – So schreiben Sie Bash-Scripts unter Linux

So verwenden Sie den Echo-Befehl in Bash-Skripten unter Linux

So komprimieren Sie eine Datei unter Linux