CSVとして解析してから、delimiter="\t"のwriterで書き出します。カンマを一括でタブに置換すると、値の中のカンマまで変わるため使えません。
この記事の内容
対象・検証範囲:CPython 3.12.14 / Linux。掲載サンプルと期待する出力を照合。標準ライブラリのみ。
区切り文字の一括置換では足りない
"ノート, A5"という値には、区切りではないカンマがあります。CSVをテキストとして一括置換すると、この商品名まで変わってしまいます。
また「TSVなら引用符が不要」とも限りません。値にタブや改行があれば、区切りとデータを見分ける規則が必要です。この記事は、受け取り側も引用符を解釈する、CSVに似たタブ区切り形式を前提にします。
値を解析してから書き直す
次の例では、入力のカンマを保持し、値の中のタブも含めて往復確認します。ターミナルではタブが見えにくいため、表示だけ<TAB>へ置き換えています。保存すべき値はtsv_textです。
import csv
import io
source = 'id,name,note\n001,"ノート, A5","青\t太字"\n'
rows = list(csv.reader(io.StringIO(source, newline=""), strict=True))
if not rows or any(len(row) != len(rows[0]) for row in rows):
raise ValueError("列数を確認してください")
output = io.StringIO(newline="")
writer = csv.writer(output, delimiter="\t", lineterminator="\n")
writer.writerows(rows)
tsv_text = output.getvalue()
print(tsv_text.replace("\t", "<TAB>"), end="")
restored = list(csv.reader(io.StringIO(tsv_text, newline=""), delimiter="\t"))
assert restored == rows
print("変換前後の値が一致")
期待する結果
id<TAB>name<TAB>note
001<TAB>ノート, A5<TAB>"青<TAB>太字"
変換前後の値が一致
「ノート, A5」のカンマは残ります。備考のタブは値の一部なので、そのフィールドは引用符で囲まれます。画面上の<TAB>は説明用の表示であり、TSVの正式な記号ではありません。
実ファイルでは入力をCSVとして読み、出力をnewline=""、文字コード指定付きで新しいファイルへ書き出します。CSVへ戻す場合は、読み込み側をタブ区切り、書き込み側をカンマ区切りにします。
連携先が引用符を理解しない場合
単純にタブで分割する取り込み先では、この形式を正しく読めないことがあります。その場合は「値の中のタブや改行を禁止する」「専用のエスケープを使う」など、相手の仕様が必要です。
値を空白へ置き換える方法もありますが、それは区切り形式の変換だけでなくデータの変更です。元データを保管し、どの文字が何に変わったかを確認できるようにしてください。仕様不明のまま引用符をすべて削除することは避けます。
確認と制限
このテストが保証するのは、Pythonのwriterが出したタブ区切りデータを、対応するreaderで読んだときの一致です。すべてのTSV利用ソフトでの互換性は検証していません。
手元のファイルに適用する前に、カンマ・タブ・引用符・改行を含む小さな例を実際の連携先へ取り込みます。文字化けが起きる場合は区切りの問題とは別なので、UTF-8とBOMの設定も確認します。大量データでは、この全件メモリー保持の例からストリーミング処理への変更が必要です。
参考にした公式資料
- Python公式: csv — CSVファイルの読み書き確認日:2026.09.20
- RFC 4180: CSVの共通形式確認日:2026.09.20
掲載サンプルは記載のPython環境で実行確認しています。すべてのOS・入力データを保証するものではありません。 編集・検証方針