수천 줄의 다음 형식으로 작성된 데이터가 포함된 텍스트 파일이 있습니다.
- 새 레코드는 항상 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;;;;;;;;;;;;;;;;