Awk

逗號分隔的文件在值中包含逗號

  • October 4, 2022

我有一個包含以下數據的文件:

“A”,”Dept1”,”i am mahesh,working in it”,”1”
“B”,”Dept2”,”i am suresh, working in non it”,”2”

我想要的輸出是:

A,Dept1,i am mahesh~working in it,1
B,Dept2,i am suresh~working in non it,2

我在下面嘗試過,但它正在用 ~ 替換 all ,如下所示:

awk -F ‘“,”’ -v OFS=‘’ ‘{for (i=0;i<=NF;++i) gsub(“,”,”~”,$i)}1’ file

“A”~”Dept1”~”i am mahesh~working in it”~”1”
“B”~”Dept2”~”i am suresh~working in non it”~”2”

嘗試seda) 將所有出現的逗號 NOT 在雙引號之間更改為波浪號,然後 b) 刪除所有雙引號:

sed 's/\([^"]\),\([^"]\)/\1~\2/g;s/"//g' infile

-i如果結果很好,請使用原地替換文件。

假設所有欄位在使用前都用引號括起來。

使用結構化文件格式時,請使用了解該特定格式的工具,而不是通用的文本處理工具。

在 CSV 文件中,除非已知它是“簡單的”,否則引用的欄位可能包含逗號和換行符。引用欄位中的引號加倍 ( "")。

要將嵌入式逗號更改為波浪號 ( ~),您最好使用 CSV 感知工具,例如mlr (Miller) 或csvkit

下面,我假設引用字元是普通的雙引號 ( "),而不是您在問題文本 ( ) 中使用的彎引號。

這是用 轉換第三個欄位mlr,這是一個方便的工具,可以辨識幾種不同的結構化格式:

$ mlr --csv -N put '$3=sub($3,",","~")' file
A,Dept1,i am mahesh~working in it,1
B,Dept2,i am suresh~ working in non it,2

--csv選項導致mlr輸入和輸出 CSV 數據,並-N告訴實用程序我們的數據沒有標題。然後我們應用put“動詞”(動作)並給它一個如果你習慣的話應該看起來很熟悉的表達式awk(儘管參數的順序sub()不同)。


使用csvformat(來自 csvkit),我們可以重新格式化數據,以便我們可以更輕鬆地找到我們想要更改的逗號。

我首先將分隔符更改為@(任何尚未包含在數據中的字元):

$ csvformat -D '@' file
A@Dept1@i am mahesh,working in it@1
B@Dept2@i am suresh, working in non it@2

然後我可以簡單地使用tr將剩餘的逗號更改為波浪號:

$ csvformat -D '@' file | tr ',' '~'
A@Dept1@i am mahesh~working in it@1
B@Dept2@i am suresh~ working in non it@2

然後再次使用將分隔符切換回逗號csvformat

$ csvformat -D '@' file | tr ',' '~' | csvformat -d '@'
A,Dept1,i am mahesh~working in it,1
B,Dept2,i am suresh~ working in non it,2

請注意,這會將所有嵌入的逗號更改為波浪號,而不僅僅是第三列中的逗號。

將結果重定向到新名稱以將其保存到文件中。

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