ファイル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.」という分野です。カンマが含まれ、これもパイプ(|)に置き換えられます。だから私はすべてを置き換えたかったのですが、値の中にないパイプを除いて、二重引用符「」を与えています.
これを行うシェルスクリプトはありますか?
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ルールに従って結果が適切に引用されていることを確認します。
少なくとも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
問題を解決するには:
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'
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
_
スタンドアロンPerl
の場合:
Perl -pe 's{"(.*?)"|,}{$1 // "|"}ge' < "$File" > "$Output"
(値に|
、"
、または改行文字が含まれていないことを前提としています)。
awk
、一度に1文字入力の各行を一度に1文字ずつ調べます。二重引用符0
が出現するたびに、カウンターq
を1
と"
の間で切り替えて、q
が1
と等しくなるようにします。二重引用符の各ペアの内側(つまり、各終了二重引用符の前)。次に、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
非常に短い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