ネストされた参照を持つcsvからtsvへ

ネストされた参照を持つcsvからtsvへ

bashでCSVをTSVに変換する必要があります。私が見つけたこれソリューションはうまく機能しますが、以下のようにすべてのデータセットに対しては機能しません。

たとえば、次のようになりますa.txt

a,"test, part2 ""the start""",b

sed無効な形式:

[ nir ]$ cat a.txt | sed -E 's/("([^"]*)")?,/\2\t/g' 
a    "test    Op. 15 ""the start"    b
#^ tab....^ tab..................^ tab

ここに問題があります:欠落,、追加タブ、追加引用符。

ちなみに、Pythonコードの形式も間違っています。

[ nir ]$ cat a.txt | csv2tsv.py
a    "test, part2 ""the start"""    b
#^ tab..........................^ tab

ここでの問題は追加の引用符です。

csv2tsv.py例: csv.writer(sys.stdout, dialect='excel-tab').writerows(csv.reader(sys.stdin))

実際の変換は次のようになります。

a    test, part2 "the start"    b
#^ tab......................^ tab

この問題を解決する方法についてフィードバックを受けたいですbash。私はインターネット上で多くの解決策を見ましたが、引用符内の引用符を処理できませんでした。 :)

ベストアンサー1

そしてmlr

mlr -N --icsv --otsvlite cat < file.csv > file.tsv

または:

mlr -N --c2t --quote-none cat < file.csv > file.tsv

ただし、csvフィールドにタブ文字が含まれていると、出力はエスケープされないため、追加のフィールドが発生します。

GNUを使用すると、sed同じことができます。

sed -E '
  # append next line as long as there is not an even number
  # of "s, to handle fields with newline. You can omit this line
  # if the fields are guaranteed not to contain newlines:
  :1; /^([^"]*"[^"]*")*[^"]*$/! {N;b1}

  s/$/,/
  s/(([^,"]*)|"((""|[^"])*)"),/\2\3\t/g
  s/\t$//
  s/""/"/g' < file.csv > file.tsv

入力は現在のロケールの有効なテキストと見なされます。まず、ローカライゼーションをsed無効にしLC_ALL=C sed...、入力をバイナリとして処理してデコードの問題を回避します(速度が問題になると速度が速くなる可能性があります)。

おすすめ記事