Linux

使用 sed、awk 或 tr 將每一行拆分為 CSV 格式,使用冒號 (:) 作為分隔符

  • April 22, 2020

我有一個龐大的客戶帳戶資訊文件,目前按這樣的方式排序,放在一列中。我正在尋找分割每一行,使用:作為分隔符。但這樣做時,對於每一行,當分開時,我想製作一個新列,將每行之後的數據:放入相應的列中。我的最終目標是將其轉換為 CSV 格式,以便在某處導入數據分析和/或建構數據庫。

firstName:John
middleName:null
lastName:Doe
companyName:John Doe Corp
suffix:null
primaryEmail:johndoe@johndoe.com
primaryPhone:555.555.5555
secondaryEmail:johndoe@johndoe.com
secondaryPhone:null

此外,這不是每個客戶的總行數。每個客戶是 55 行。

使用perl,它存在於任何桌面或伺服器 Linux 發行版上:

perl -lne '
  BEGIN{$,=","}
  ($k,$v)=split":",$_,2;
  next unless defined $v;
  for($k,$v){s/"/""/g,$_=qq{"$_"}if/[$,"]/}
  $k=$t{$k}//=$t++;
  if(exists$f[$k]){print@f;@f=()}
  $f[$k]=$v;
  END{print@f;print STDERR sort{$t{$a}<=>$t{$b}}keys%t}
' your_file

這應該將文件轉換為標準 CSV,除了在處理整個文件後,標題(帶有欄位名稱的第一行)將列印到標準錯誤中。... >body 2>hdr您可以使用然後將其保存在某處cat hdr body > final_file.csv

這對空行等沒有任何特殊意義:一條記錄被視為由一組具有不同名稱的欄位組成,無論它們的順序如何。

包含,或的欄位"將被放入 inside "...",並且任何內部"都將通過將其加倍來轉義""(使用 CSV 約定)。

$,=","您可以通過更改為例如來調整欄位分隔符。$,="|"(或$,="\t"標籤)。for($k,$v){ ... }您可以通過刪除該行來擺脫引用和轉義。

這可以在awk(不在sedortr中)完成,只是它會更複雜一些,因為awk無法一次列印整個數組(您必須循環遍歷它們),也無法將字元串拆分為有限數量的欄位(您必須為此使用substr技巧)。

引用自:https://unix.stackexchange.com/questions/580591