在特定字串之間查找並添加引號

在特定字串之間查找並添加引號

當我使用 csv 時,不需要的逗號(',')會誤導我的 csv 文件,導致不一致。

請在下面詳細了解。

我的範例 csv 檔案:

1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4

我想要的最終結果為:

1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4

添加引號後,我將替換“|”與“,”這樣我的csv將按我的預期工作。

我使用了下面的命令,但它沒有按預期給出。

sed -e 's/,/"&"/' file1.txt

答案1

使用csvformat來自csvkit,並假設最終結果應該是一個以逗號作為分隔符號的 CSV 檔案(如問題文本中所述):

$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4

這會將 CSV 檔案的格式從使用|- 字元作為分隔符號重新設定為使用預設逗號作為分隔符號。這樣做時,它正確地引用了需要引用的欄位。

這也可以正確處理帶有嵌入換行符的欄位:

$ cat file
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
2|"line 1,
line2"|5
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
2,"line 1,
line2",5

如果您有某種結構化文檔格式的文檔,例如 CSV、JSON、XML、YAML、TOML 等,則沒有理由不是使用該文件格式的解析器來解析該文件。

答案2

你可以這樣做:

awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile

我們-F'[|]'定義了輸入欄位分隔符號。
我們-v OFS=','定義了輸出欄位分隔符號。
NF根據 FS(輸入字段分隔符號)確定每行/記錄中有多少個字段,因此我們循環遍歷字段數並為每個字段添加雙引號,並在該行上列印最終更新awk 的1習慣用法用於列印。

請注意,所有欄位都被此命令引用,這顯然對於擁有有效的 CSV 檔案來說不是問題。

答案3

sed

$ sed 's/[^|]*,[^|]*/"&"/g; y/|/,/' ip.txt
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
  • s/[^|]*,[^|]*/"&"/g將雙引號添加到包含以下內容的所有字段,
  • y/|/,/將所有|字元變更為,

perl

perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'

這用作|輸入欄位分隔符號。然後map將為所有包含 的字段添加雙引號,。最後,join用於將字段與,字元組合起來。

答案4

其他sed方式:

  sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data

或者,如果您sed支援加載ERE,例如GNU sed,您可以避免所有轉義作業:

  sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data

您可以利用這樣一個事實,即只有中間組|在每個邊界處由 a 分隔,並使長度變得sed更短:

sed 's;|\([^|]*\)|;,"\1",;' data

當然也在這裡,如果您的 sed 支持,-E您可以加載ERE並避免繁瑣的轉義工作

相關內容