数千行の次の形式で作成されたデータを含むテキストファイルがあります。
- 新しいレコードは常に WHATEVER.RDNDISPLAY または WHATEVER.DSPLY_NAME で始まります。
- レコード名はWHATEVERです。
- 行は「次にスペースが続きます。これはデータがないか、テキスト、日付、文字列、または数字+100または-100を意味します。
- 以下のスペースはないので無視してください。これは、このサイトでこれを正しく表示する方法を確認するためのものです。したがって、フラットファイルの各レコードには数千の行があります。
計画
Field separator
v v quote followed by blank or data (numbers or text or even + or -)
TEST_AP.RDNDISPLAY "
^ ^ Field Name
Record name
はい
---------------
TEST_AB.RDNDISPLAY "
TEST_AB.DSPLY_NAME "
TEST_AB.TIMACT "
TEST_AB.NETCHNG_1 "
TEST_AB.TRADE_DATE "
TEST_AB.ACTIV_DATE "
TEST_AB.BID "
TEST_AB.ASK "
TEST_AB.MATUR_DATE "
TEST_AB.COUPN_RATE "
TEST_AB.MID_PRICE "
TEST_AB.MKT_MKR_NM "
TEST_AB.RECORDTYPE "
TEST_AB.SETTLEDATE "
TEST_AB.BID_YIELD "
TEST_AB.ASK_YIELD "
TEST_AB.GEN_VAL1 "
TEST_AB.GEN_VAL2 "
TEST_AB.GEN_VAL3 "
TEST_AB.GEN_VAL4 "
TEST_AB.SPARE_NM1 "
TEST_AB.SPARE_NM2 "
TEST_AB.SPARE_NM3 "
TESTRICU=L.DSPLY_NAME "TEST
TESTRICU=L.TIMACT "
TESTRICU=L.TRDPRC_1 "
TESTRICU=L.CURRENCY "GBP
TESTRICU=L.TRADE_DATE "
TESTRICU=L.TRDTIM_1 "
TESTRICU=L.OPEN_PRC "
TESTRICU=L.HST_CLOSE "
TESTRICU=L.BID "
TESTRICU=L.ASK "0
TESTRICU=L.BIDSIZE "
TESTRICU=L.ASKSIZE "
TESTRICU=L.YIELD "
TESTRICU=L.PERATIO "
TESTRICU=L.PCTCHNG "
TESTRICU=L.CLOSE_BID "
TESTRICU=L.CLOSE_ASK "
TESTRICU=L.STRIKE_PRC "
TESTRICU=L.MATUR_DATE "31 Dec 1906
TESTRICU=L.COUPN_RATE "+4
TESTRICU=L.OFFCL_CODE "1003
TESTRICU=L.HSTCLSDATE "
TESTRICU=L.BOND_TYPE "
TESTRICU=L.BCKGRNDPAG "
TESTRICU=L.ISSUE_DATE "01 Jan 2004
TESTRICU=L.PUTCALLIND "
TESTRICU=L.NAVALUE "
TESTRICU=L.NAV_NETCHN "
TESTRICU=L.MID_PRICE "
TESTRICU=L.EUROCLR_NO "
TESTRICU=L.CEDEL_NO "
TESTRICU=L.VALOREN_NO "100
TESTRICU=L.NAVDATE "
TESTRICU=L.NAVALUE_1 "
TESTRICU=L.NAVDAT_1 "
TESTRICU=L.PRTY_PRICE "
TESTRICU=L.ISSUE_PRC "
このファイルをExcelで列形式で読み取れる表形式に抽出し、行にデータ値を入力できるようにしたいです。だから出力は次のようになります
RECORDNAME RDNDISPLAY DSPLY_NAME CURRENCY TIMACT NETCHNG_1 TRADE_DATE ACTIV_DATE BID ASK MATUR_DATE COUPN_RATE OFFCL_CODE ISSUE_DATE VALOREN_NO .... so on
TEST_AB ;
TESTRICU=L ; ;TEST ; GBP ; ; ; ; ; 0 31 Dec 1906 ; +4 ; 1003 ; 01 Jan 2004 ; 100 .... so on
したがって、コードはすべての可能なフィールド名を見つけ、ファイルを再度読み込み、RDNDISPLAYまたはDSPLY_NAMEを検索してレコードの開始と終了(他のレコードの先頭)を特定し、レコード名(たとえば何でも)を抽出し、各場所のフィールドの下に行形式のフィールドのタイトルです。各レコードに対してこれを行い、元の名前がファイルにない場合は、Excelにインポートして簡単に実行できます。
答え1
CSVにはいくつかのトリッキーな問題があります。フィールドにフィールド区切り文字が含まれているか、フィールドに引用符が含まれています。サンプルデータに2行を追加しました。
TEST_AB.foo " with "embedded quotes" here
TESTRICU=L.foo " with an inner; semicolon
恐ろしいPerlソリューションは、「text2csv.sh」というファイルに保存することです。
#!/bin/sh
perl -lne '
@F = split /\s*"\s*/, $_, 2;
($record, $field) = split /\./, $F[0];
$fields{$field} = 1;
$records{$record} = 1;
$data{$record}{$field} = $F[1];
} END {
print join ";", "RECORDNAME", keys %fields;
for my $rec (keys %records) {
print join";", $rec, map {
$q=0;
if (/"/) {s/\"/\"\"/g; $q=1}
if (/;/) {$q=1}
$q ? qq{"$_"} : $_
} @{$data{$rec}}{keys %fields};
}
' "$1" > "$1.csv"
次のように実行してください。
sh text2csv.sh /path/to/myfile.txt
cat /path/to/myfile.txt.csv
RECORDNAME;PERATIO;NAVALUE_1;ISSUE_PRC;BCKGRNDPAG;GEN_VAL2;SPARE_NM2;GEN_VAL3;COUPN_RATE;DSPLY_NAME;CLOSE_BID;NAVALUE;VALOREN_NO;TRDTIM_1;PRTY_PRICE;ISSUE_DATE;RECORDTYPE;OFFCL_CODE;MID_PRICE;BID;TRDPRC_1;ASK;ACTIV_DATE;STRIKE_PRC;HSTCLSDATE;ASK_YIELD;MATUR_DATE;NAV_NETCHN;NAVDATE;PCTCHNG;TRADE_DATE;BIDSIZE;NAVDAT_1;ASKSIZE;MKT_MKR_NM;foo;OPEN_PRC;NETCHNG_1;BID_YIELD;RDNDISPLAY;YIELD;CURRENCY;TIMACT;GEN_VAL1;HST_CLOSE;PUTCALLIND;CLOSE_ASK;SPARE_NM3;BOND_TYPE;SPARE_NM1;SETTLEDATE;EUROCLR_NO;GEN_VAL4;CEDEL_NO
TESTRICU=L;;;;;;;;+4;TEST;;;100;;;01 Jan 2004;;1003;;;;0;;;;;31 Dec 1906;;;;;;;;;"with an inner; semicolon";;;;;;GBP;;;;;;;;;;;;
TEST_AB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"with ""embedded quotes"" here";;;;;;;;;;;;;;;;;;
答え2
あなたが好きならawk
:
awk -F' *[."]' '
{
FName[$2]=1
RName[$1]=1
Data[$1,$2]=$3
}
END{
printf("%s;","RECORDNAME")
for (f in FName)
printf ("%s;",f)
print ""
for (i in RName){
printf ("%s",i)
for (j in FName)
printf ("%s;",Data[i,j])
print ""
}
}' text.file
出力:
RECORDNAME;BID_YIELD;PCTCHNG;NAVALUE_1;EUROCLR_NO;ACTIV_DATE;MKT_MKR_NM;PRTY_PRICE;NAV_NETCHN;ASKSIZE;TRDTIM_1;HST_CLOSE;CLOSE_BID;SPARE_NM1;CURRENCY;SPARE_NM2;SPARE_NM3;TRDPRC_1;NAVDATE;DSPLY_NAME;CLOSE_ASK;OPEN_PRC;MATUR_DATE;BCKGRNDPAG;STRIKE_PRC;OFFCL_CODE;ASK_YIELD;ISSUE_PRC;VALOREN_NO;BOND_TYPE;ISSUE_DATE;PUTCALLIND;RDNDISPLAY;BID;MID_PRICE;COUPN_RATE;RECORDTYPE;ASK;NAVALUE;TIMACT;YIELD;NETCHNG_1;PERATIO;SETTLEDATE;HSTCLSDATE;NAVDAT_1;GEN_VAL1;GEN_VAL2;CEDEL_NO;GEN_VAL3;GEN_VAL4;BIDSIZE;TRADE_DATE;
TEST_AB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TESTRICU=L;;;;;;;;;;;;;GBP;;;;;TEST;;;31 Dec 1906;;;1003;;;100;;01 Jan 2004;;;;;+4;;0;;;;;;;;;;;;;;;;