
次のaaファイルがあります.csv
。
"ID0054XX","PT. SUMUT","18 JL.BONJOL","SUMATERA UTARA, NORTH","MEDAN","","ID9856","PDSUIDSAXXX","","","","Y"
"ID00037687","PAN INDONESIA, PT.","JALAN JENDERAL, SUDIRMAN, SENAYAN","","INDIA","","ID566543","PINBIDJAXXX","","0601","","Y"
,
区切り文字として使用される一意の変数に、各コンマ区切り値を割り当てるスクリプトがあります。
スクリプトの部分は次のとおりです。
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read Key Name Address1 Address2 City State Country SwiftCode Nid Chips Aba IsSwitching
do
echo "-------------------------------------------------------------------"
echo "From Key : $Key"
echo "-------------------------------------------------------------------"
echo "-------------------------------------------------------------------"
echo "From Name : $Name"
それがすることは、引用符の中のコンマで値を分離することであり、私が望む出力は各値をその変数から一意に分離することです。
私はコンマを変更しようとしましたが、IFS=[","]
成功しませんでした。どんなアドバイスや助けにも感謝します。
答え1
ここでいくつかの誤りを犯しています。
-
これは可能ですが、非常に非効率的です。遅くて書くのが難しく、読みにくく、正しく実行するのが難しいです。シェルはこの種の操作のために設計されていません。
csvパーサーなしでcsvファイルを解析しようとしています。
CSVは単なる形式ではありません。ここに示すように、区切り文字を含むフィールドを持つことができます。複数行にまたがるフィールドを持つこともできます。単純なパターンマッチングを使用して任意のCSVデータを解析することは、非常に複雑で正確に実行するのが非常に困難です。
悪くてハッキーな解決策は次のとおりです。
$ sed 's/","/"|"/g' file.csv |
while IFS='|' read -r Key Name Address1 Address2 City \
State Country SwiftCode Nid Chips Aba IsSwitching; do
echo "From Key : $Key"; echo "From Name : $Name";
done
From Key : "ID0054XX"
From Name : "PT. SUMUT"
From Key : "ID00037687"
From Name : "PAN INDONESIA, PT."
","
これは区切り文字として"|"
使用されているすべてを置き換えます|
。もちろん、フィールドに|
。
良い、きれいな方法は、適切なスクリプト言語(シェルではない)とcsvパーサーを使用することです。たとえば、Perl 1では次のようになります。
$ cat file.csv | perl -MText::CSV -le '
$csv = Text::CSV->new({binary=>1});
while ($row = $csv->getline(STDIN)){ my ($Key, $Name, $Address1, $Address2, $City, $State, $Country, $SwiftCode, $Nid, $Chips, $Aba, $IsSwitching) = @$row;
print "From Key: $Key\nFrom Name: $Name";}'
From Key: ID0054XX
From Name: PT. SUMUT
From Key: ID00037687
From Name: PAN INDONESIA, PT.
またはスクリプトとして:
#!/usr/bin/perl -l
use strict;
use warnings;
use Text::CSV;
open(my $fh, "file.csv");
my $csv = Text::CSV->new({binary=>1});
while (my $row = $csv->getline($fh)){
my (
$Key, $Name, $Address1, $Address2, $City,
$State, $Country, $SwiftCode, $Nid, $Chips,
$Aba, $IsSwitching
) = @$row;
print "From Key: $Key\nFrom Name: $Name";
}
Text::CSV
モジュールを最初にインストールする必要があります()、(ほとんどのディストリビューションではパッケージ)をインストールする必要がcpanm Text::CSV
あります。cpanm
cpanminus
または、Python 3では次のようになります。
#!/usr/bin/env python3
import csv
with open('file.csv', newline='') as csvfile:
linereader = csv.reader(csvfile, delimiter=',', quotechar='"')
for row in linereader:
print("From Key: %s\nFrom Name: %s" % (row[0], row[1]))
上記のPythonコードをスクリプトとして保存してファイルから実行すると、次のものが印刷されます。
$ foo.py
From Key: ID0054XX
From Name: PT. SUMUT
From Key: ID00037687
From Name: PAN INDONESIA, PT.
1はい、これがUUoCであることはわかりますが、このように1行で書く方が簡単です。