AWK 指令參數錯誤

AWK 指令參數錯誤

我有一個資料集,其中包含學生的聯絡資訊,範例資料集如下

First Name, Last Name, Address, Phone Number
John, Doe, "House # 11, Street xyz, Road, Area",00000000
Sara, Taylor, "Jake Lake%, Apartment #22, Main Road, Area XYZ", 00000000

我正在運行以下命令來替換,網址列中的|將其載入到資料庫中。

awk '!(NR%2){gsub(",","|")} {printf RFS $0} {RFS="\""}' RS=\" fileName.txt > output.txt

我面臨的問題是每當我運行此命令時它都會返回以下錯誤,最初它運行正常

awk: run time error: not enough arguments passed to printf(""Jake Lake%, Apartment #22, Main Road, Area XYZ")

有什麼解決辦法嗎?我注意到%地址中出現的是這個問題嗎?

答案1

  1. 為了穩健性,永遠不要這樣做printf $0,總是使用相反,因為當您的輸入包含格式字元(如您目前所看到的)printf "%s", $0時,前者會失敗。printf這同樣適用於使用printf任何輸入資料。
  2. 為了清晰和穩健,切勿使用全大寫的變數名稱,例如,RFS以避免與內建變數名稱發生衝突,並避免使程式碼看起來像是在使用內建變量,而實際上並未使用內建變數。
  3. 為了可讀性,請不要設定變量,例如RS,在腳本之後,除非您需要為不同的輸入檔案將它們設定為不同的值,在腳本之前或開始時設定變量,這樣在讀取腳本時我們會看到它們在我們之前設置看到它們被使用。
  4. 為了效率、簡單性、穩健性,*sub() 的第一個參數是正規表示式,而不是字串,因此請使用正規表示式 ( /.../),而不是字串 ( "...") 分隔符,除非您出於某些原因需要動態而不是靜態正規表示式。
  5. 為了清楚起見和可維護性,當您有兩個必須具有相同值的變數時,例如RSRFS,不要將它們單獨設定為相同的值,例如RS="\""; RFS="\"",或將它們一起設定為該值,例如RS=RFS="\""或將其中一個設定為另一個,例如RS="\""; RFS=RS

這是正確編寫問題中的程式碼的方法:

$ awk -v RS='"' '!(NR%2){gsub(/,/,"|")} {printf "%s%s", rfs, $0; rfs=RS}' file
First Name, Last Name, Address, Phone Number
John, Doe, "House # 11| Street xyz| Road| Area",00000000
Sara, Taylor, "Jake Lake%| Apartment #22| Main Road| Area XYZ", 00000000

若要使用 awk 對 CSV 執行更多操作,請參閱使用 awk 高效解析 csv 的最穩健方法是什麼

答案2

RFS您得到的錯誤是由於使用(空變數)的值和$0作為格式字串與 的串聯printf

您的文件是有效的 CSV 文件,除了一些分隔逗號後面有空格(這會擾亂字段的引用Address;引用的字段需要在分隔符後面直接包含初始引號字符)。我們可以使用csvformat(來自 csvkit 的一部分)來修正此問題https://csvkit.readthedocs.io/en/latest/):

$ csvformat --skipinitialspace file.csv >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,"House # 11, Street xyz, Road, Area",00000000
Sara,Taylor,"Jake Lake%, Apartment #22, Main Road, Area XYZ",00000000

可以解析 CSV 的資料庫應該能夠原樣讀取它。

您是否仍想將所有嵌入的逗號替換為|,只需將文件的分隔符號更改為逗號以外的其他內容(我將使用下面的製表符),將所有剩餘的逗號更改為管道,然後再次更改回使用逗號作為分隔符號。

我們可以直接對原始資料執行此操作:

$ csvformat --skipinitialspace --out-tabs file.csv | tr ',' '|' | csvformat --tabs >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,House # 11| Street xyz| Road| Area,00000000
Sara,Taylor,Jake Lake%| Apartment #22| Main Road| Area XYZ,00000000

使用的各種長選項的短變體是-Sfor --skipinitialspace-Tfor--out-tabs-tfor --tabs

相關內容