![](/img/trans.png)
[英]Swap column x of tab-separated values file with column x of second tsv file
[英]How do I convert a tab-separated values (TSV) file to a comma-separated values (CSV) file in BASH?
我有一些 TSV 文件需要轉換為 CSV 文件。 BASH 中是否有任何解決方案,例如使用
awk<\/code>來轉換這些?
我可以像這樣使用
sed<\/code> ,但我擔心它會犯一些錯誤:
sed 's/\t/,/g' file.tsv > file.csv
更新:以下解決方案通常並不健壯,盡管它們確實適用於 OP 的特定用例; 請參閱底部以獲取強大的基於awk
的解決方案。
總結一下這些選項(有趣的是,它們的表現都差不多):
時間:
devnull的解決方案(在對問題的評論中提供)是最簡單的:
tr '\t' ',' < file.tsv > file.csv
sed :
鑒於輸入不包含帶引號的字符串(可能嵌入\\t
字符),OP 自己的sed
解決方案非常好:
sed 's/\t/,/g' file.tsv > file.csv
唯一需要注意的是,在某些平台(例如 macOS)上,不支持轉義序列\\t
,因此是文字制表符。 必須使用 ANSI 引用 ( $'\\t'
) 拼接到命令字符串中:
sed 's/'$'\t''/,/g' file.tsv > file.csv
awk :
awk
的警告是FS
- 輸入字段分隔符 - 必須明確設置為\\t
- 否則默認行為將剝離前導和尾隨制表符,並僅用一個,
替換多個制表符的內部跨度:
awk 'BEGIN { FS="\t"; OFS="," } {$1=$1; print}' file.tsv > file.csv
請注意,簡單地將$1
分配給自身會導致awk
使用OFS
(輸出字段分隔符)重建輸入行; 這有效地替換了所有\\t
字符。 與,
字符。 print
然后簡單地打印重建的行。
強大的awk
解決方案:
正如A. Rabus指出的那樣,上述解決方案不能正確處理本身包含,
字符的未加引號的輸入字段 - 您最終會得到額外的 CSV 字段。
以下awk
解決方案通過按需將這些字段包含在"..."
來解決此問題(請參閱上面的非穩健awk
解決方案以獲取對該方法的部分說明)。
如果這些字段還嵌入了"
字符""
,則根據RFC 4180將它們轉義為""
。謝謝, Wyatt Israel 。
awk 'BEGIN { FS="\t"; OFS="," } {
rebuilt=0
for(i=1; i<=NF; ++i) {
if ($i ~ /,/ && $i !~ /^".*"$/) {
gsub("\"", "\"\"", $i)
$i = "\"" $i "\""
rebuilt=1
}
}
if (!rebuilt) { $1=$1 }
print
}' file.tsv > file.csv
$i ~ /[,"]/ && $i !~ /^".*"$/
檢測任何包含,
和/或"
且尚未用雙引號括起來的字段
gsub("\\"", "\\"\\"", $i)
轉義嵌入的"
字符。 通過將它們加倍
$i = "\\"" $i "\\""
通過將結果括在雙引號中來更新結果
如前所述,更新任何字段都會導致awk
從具有OFS
值的字段重建行,即,
在這種情況下,這相當於有效的 TSV -> CSV 轉換; rebuilt
標志用於確保每個輸入記錄至少重建一次。
這也可以通過 Perl 實現:
為了將結果通過管道傳輸到新的輸出文件,您可以使用以下命令:
perl -wnlp -e 's/\\t/,/g;' input_file.tsv > output_file.csv
如果您想就地編輯文件,可以調用 -i 選項:
perl -wnlpi -e 's/\\t/,/g;' input_file.txt
如果您偶然發現您處理的實際上不是制表符,而是多個空格,您可以使用以下內容用逗號替換每次出現的兩個或多個空格:
perl -wnlpi -e 's/\\s+/,/g;' input_file
請記住, \\s
代表任何空白字符,包括空格、制表符或換行符,並且不能在替換字符串中使用。
tr 命令:
tr '\t' ',' < file.tsv > file.csv
很簡單,即使在一個非常大的文件(大約 10 GB)上也為我提供了絕對正確且非常快速的結果。
使用awk對我有用
將 tsv 轉換為 csv
awk 'BEGIN { FS="\t"; OFS="," } {$1=$1; print}' file.tsv > file.csv
或將 csv 轉換為 tsv
awk 'BEGIN { FS=","; OFS="\t" } {$1=$1; print}' file.csv > file.tsv
您可以簡單地在 shell 中使用
sed<\/code>的強大功能:
sed -r 's/\t/","/g' file.tsv|sed -r 's/(^|$)/"/g' > file.csv
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.