web-dev-qa-db-ja.com

二重引用符内の場合を除き、コンマを縦棒|に置き換え、二重引用符を削除します

ファイル1

12584,"Capital of America, Inc.",,HORIZONCAPITAL,USA,......etc
25841,"Capital of America, Inc.",,HORIZONCAPITAL,USA,......etc
87455,"Capital of America, Inc.",,HORIZONCAPITAL,USA,......etc

出力

12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc

私はcsvファイルを持っています。パイプ(|)で区切られたテキストファイルに変換する必要があります。シェルスクリプトsed 's/^/"/;s/,/|/g;s/$/"/' $File > $Output

しかし問題は「Capital of America、Inc.」という分野です。カンマが含まれ、これもパイプ(|)に置き換えられます。だから私はすべてを置き換えたかったのですが、値の中にないパイプを除いて、二重引用符「」を与えています.

これを行うシェルスクリプトはありますか?

7
Juhan

csvkit を使用:

$ csvformat -D '|' file.csv
12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc

csvkitは、Pythonで記述されたCSV操作/クエリツールのコレクションです。これらは適切なCSV解析を行い、csvformatを使用してデフォルトのカンマ区切り文字を他の文字に置き換えることができます。ユーティリティは、CSVルールに従って結果が適切に引用されていることを確認します。

22
Kusalananda

少なくともDebianベースのシステムでは、OCamlベースのcsvtoolをインストールできるはずです

$ csvtool -u '|' cat file.csv
12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc

PerlのText::CSVモジュールを使用することもできます。

$ Perl -MText::CSV -lne '
  BEGIN{$p = Text::CSV->new()} 
  print join "|", $p->fields() if $p->parse($_)
' file.csv
12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
8
steeldriver

問題を解決するには:

awk 'BEGIN{FS=",";OFS="|";} {print $1,$2","$3,$4,$5,$6,$7}' Test | tr -d \"

このような一般化された問題には、GNU awkには[〜#〜] fpat [〜#〜]特殊変数がフィールドの説明:

awk -vFPAT='[^,]*|("[^"]*")' -vOFS='|' '{$1=$1;print}' Test | tr -d \"
12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc

awkおよびsedツールを使用すると、追加のパッケージは必要ありません。 [〜#〜] edit [〜#〜]as Issak と記載されているため、回答を更新します:

awk -vFPAT='[^,]*|(["].*["])' -vOFS='|' '{print $1,$2,$3,$4,$5,$6}' Test | sed 's/\"//g'
2
Hossein Vatani

SEDの使用:

オプション1:

_sed -e 's#,\([^ ]\)#|\1#g;s#"##g;s#|,#||#g' file

12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
_
  • \([^ ]\)スペースが後に続かないすべてのコンマを置き換えます。
  • 次に、_"_を削除し、_|_で始まるコンマを置き換えます。

通常、コンテキストでは、コンマとスペースを使用します。そうでない場合は、以下のコードを試してください。

オプション2:

_sed -e  's#^#\n#;:a;s#\n\([^,"]\|"[^"]*"\)#\1\n#;ta;s#\n,#|\n#;ta;s#\n##;s#"##g' file

12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
_
2
msp9011

スタンドアロンPerlの場合:

Perl -pe 's{"(.*?)"|,}{$1 // "|"}ge' < "$File" > "$Output"

(値に|"、または改行文字が含まれていないことを前提としています)。

2

awk、一度に1文字

入力の各行を一度に1文字ずつ調べます。二重引用符0が出現するたびに、カウンターq1"の間で切り替えて、q1と等しくなるようにします。二重引用符の各ペアの内側(つまり、各終了二重引用符の前)。次に、qに応じて、コンマ,をパイプ文字|に変更します。各行が評価された後、変更された行を印刷します。

awk '{
  m=""
  q==0
  for (n=1;n<=length($0);n++) {
    p=substr($0,n,1)
    if (p=="\"") { p="" ; q=(q+1)%2 }
    if (p=="," && q==0) p="|"
    m=m p
    }
  print m
  }' file.csv

入力:

12584,"Capital of America, Inc.",,HORIZONCAPITAL,USA,......etc
25841,"Capital of America, Inc.",,HORIZONCAPITAL,USA,......etc
87455,"Capital of America, Inc.",,HORIZONCAPITAL,USA,......etc

出力:

12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
1
Gaultheria

非常に短いPython csvモジュールを使用するスクリプト:

import csv,sys

with open(sys.argv[1]) as csvfile:
    csvr = csv.reader(csvfile)
    for line in csvr:
        print('|'.join(line))

これは次のように機能します。

$ python3 csvfile.py input.csv
12584|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
25841|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
87455|Capital of America, Inc.||HORIZONCAPITAL|USA|......etc
0