如何在Bash中解析CSV檔案


CSV檔案是一種我們在網際網路上廣泛使用的常見檔案格式。它們基本上是一種由行組成的檔案型別,每一行都被視為一個簡單的表格中的行。顧名思義,CSV(逗號分隔值)意味著每一行中的資料都由逗號分隔。

CSV檔案只是純文字,我們可以在任何編輯器中檢視和編輯它們。我們使用這種型別的檔案常見的欄位包括電子表格、資料庫、儲存配置資料以及API之間的資料交換。

在Linux中,有很多方法可以解析這樣的檔案。在本教程中,我們將介紹使用Bash指令碼解析CSV檔案的不同方法。

CSV檔案示例

為了瞭解如何處理CSV檔案,我們首先需要了解這些檔案中的資料是如何組織的。

假設我們有一個名為example.csv的檔案,其內容如下:

Name,Age,City
John Doe,28,New York
Jane Smith,34,Los Angeles
Sam Johnson,25,Chicago
Emily Davis,40,Houston

正如你所看到的,我們有幾行,每一行都使用逗號來分隔資料。你的檔案可能很長且很複雜,但結構保持不變。

使用cut命令

cut命令可以用於任何型別的文字檔案,而不僅僅是CSV檔案。在我們的例子中,我們可以用它來解析CSV檔案。如果你正在尋找檔案內的特定資料,cut命令非常有用。

cut命令的語法很簡單。我們傳遞命令名稱,然後是-d選項來指定我們需要使用的分隔符(在我們的例子中,它將是一個逗號),然後是-f選項來指定我們正在處理的列號。

Bash中cut命令的示例

以下是Bash中使用cut命令的一些示例:

示例1:從全名中獲取名字

在示例檔案中,姓名位於第一列,最後提供的是我們的檔名:

cut -d "," -f 1 example.csv

如果我們執行這個命令,應該會得到這樣的輸出

Name
John Doe
Jane Smith
Sam Johnson
Emily Davis

我們得到了命令選項中指定的第1列。在你的情況下,這可能會有所不同,具體取決於你正在處理的檔案,因此請根據需要調整命令。

一旦我們得到第一列,我們需要更具體地只獲取名字。為此,我們可以再次使用cut命令,但這次我們將使用空格作為分隔符,因為如果你注意的話,全名在名字和姓氏之間有一個空格(John Doe)。

此命令的語法如下:

cut -d "," -f 1 example.csv | cut -d " " -f 1

我們使用管道(|)將顯示全名的第一個輸出傳遞給另一個cut命令,該命令將獲取第一列,分隔符是空格(" ")。如果你的分隔符不是空格,請相應地調整它。

如果我們執行這個命令,我們應該得到想要的結果:

Name
John
Jane
Sam
Emily

示例2:從名字中獲取第一個字元

cut命令的功能不止於此。我們可以使用字元而不是常規分隔符來分割和過濾結果。

例如,假設我們需要獲取名字中的第一個字元。我們該怎麼做呢?我們可以使用另一個選項-c,它處理字元,如下所示:

cut -d "," -f 1 example.csv | cut -d " " -f 1 | cut -c 1

這將給我們這樣的輸出

N
J
J
S
E

我們第三次使用了cut,並將值1傳遞給-c選項,以獲取名稱中的第一個字元。

示例3:獲取除第一個字元以外的其餘名稱

如果我們需要獲取除第一個字元以外的其餘名稱呢?我們可以這樣做:

cut -d "," -f 1 example.csv | cut -d " " -f 1 | cut -c 2-

在這裡,我們從第二個字元開始,使用(-)獲取單詞的其餘部分。輸出將是:

ame
ohn
ane
am
mily

你可以根據需要對輸出做任何你想做的事情——將其儲存到檔案、對其進行排序或將其傳遞給另一個命令。

再舉一個例子來演示cut命令的功能:在前面的例子中,我們只提取了一列。但是,如果你想提取多列,你可以使用-f選項,如下所示:

cut -d "," -f 1,2 example.csv

這將給我們第一列和第二列。請記住,我們的示例檔案有三列。輸出將是:

Name,Age
John Doe,28
Jane Smith,34
Sam Johnson,25
Emily Davis,40

如果你想獲取例如第一列和第三列,你可以像這樣調整命令:

cut -d "," -f 1,3 example.csv

使用自定義Shell指令碼

我們可以根據需要解析和格式化輸出的另一種方法是使用自定義shell指令碼

在Bash指令碼中,我們有很多方法可以進行解析。我們可以使用cut,就像我們在前面的例子中看到的那樣,或者使用awk,或者我們可以使用簡單的迴圈逐行讀取檔案。

在與CSV檔案相同的目錄下,建立一個Bash檔案(例如,parse.sh)並用以下程式碼填充它:

#!/bin/bash

IFS=","

while read -r col1 col2 col3
do
   echo "Person Name: $col1"
   echo "Person Age : $col2"
   echo "City       : $col3"
done < example.csv

讓我們理解這段程式碼的作用:

  • #!/bin/bash − 這告訴shell這個檔案是一個Bash指令碼。
  • IFS="," − 這代表內部欄位分隔符,用於分隔欄位的字元(在本例中為逗號)。
  • while read -r col1 col2 col3 − 我們啟動一個迴圈,逐行讀取檔案並將每個欄位的內容儲存在一個變數中。在本例中,我們有三個變數,但根據檔案內容,可以更多。
  • echo − 用於格式化輸出並使其更易讀。
  • done < example.csv − 這指定我們想要從中讀取的檔案。

如果我們執行這個命令,我們應該會得到這樣的結果:

Person Name: Name
Person Age : Age
City       : City
Person Name: John Doe
Person Age : 28
City       : New York
Person Name: Jane Smith
Person Age : 34
City       : Los Angeles
Person Name: Sam Johnson
Person Age : 25
City       : Chicago
Person Name: Emily Davis
Person Age : 40
City       : Houston

因為我們逐行讀取檔案,我們也得到了第一行(Name, Age, City),這不是我們需要的。我們如何忽略這一行呢?

我們可以這樣做:

#!/bin/bash

IFS=","
((first = -1))

while read -r col1 col2 col3
do
   ((first++)) 
   if [ "$first" = 0 ]; then    
      continue         
   fi
   echo "Person Name: $col1"
   echo "Person Age : $col2"
   echo "City       : $col3"
done < example.csv

我們添加了一個名為first的變數,其值為-1。在迴圈中,我們遞增變數((first++))並檢查變數是否等於0。如果是,我們跳過該行並從下一行開始。

結果,我們應該得到:

Person Name: John Doe
Person Age : 28
City       : New York
Person Name: Jane Smith
Person Age : 34
City       : Los Angeles
Person Name: Sam Johnson
Person Age : 25
City       : Chicago
Person Name: Emily Davis
Person Age : 40
City       : Houston

Bash指令碼是一種功能強大的語言,擁有許多我們可以用來完成幾乎所有需要完成的任務的工具。這只是一個例子;你可以根據需要進行調整。

結論

在本教程中,我們解釋了在Bash中解析CSV檔案的一些方法。我們從cut實用程式開始,它具有許多功能並且易於使用。然後,我們使用了一個自定義Bash指令碼,它遍歷檔案並逐行讀取它,我們可以根據檔案和我們的需要進行調整。

更新於:2024年11月4日

28 次瀏覽

開啟你的職業生涯

完成課程獲得認證

開始學習
廣告