2016-05-16 8 views
1

に壊れた引用符とコロンで区切られた値を解析、私はこのようになりますコロンで区切られたファイルcik.coleft.cを、持っている:bashの

!J INC:0001438823: 
#1 A LIFESAFER HOLDINGS, INC.:0001509607: 
#1 ARIZONA DISCOUNT PROPERTIES LLC:0001457512: 
#1 PAINTBALL CORP:0001433777: 
$ LLC:0001427189: 
& S MEDIA GROUP LLC:0001447162: 
&TV COMMUNICATIONS INC.:0001479357: 
'MKTG, INC.':0000886475: 
11:11 CAPITAL CORP.:0001463262: 

それは分離カンマはコロンに置き換えた2列csvです。一方、一重引用符は、コロン(セパレータ)を使用した値ではなく、カンマで値をエスケープします。

ただし、最初の列にはコロンが含まれています。このコロンはパーサーを中断します。私は...通常csv

curl -o cik.coleft.c 'https://www.sec.gov/edgar/NYU/cik.coleft.c' 

in2csv --format 'csv' -d ':' -q "'" -e 'latin1' cik.coleft.c > cik.coleft.csv 

cik.coleft.cを変換しようとするので...私は4と複数の列を取得します。

私はsedにラインを読んでみましたが、成功していません。

これを適切な2列テーブルに変換するにはどうすればよいですか?

+0

「11:11」などと競合しない別の区切り文字を選択できますか? –

+0

したがって、間違った唯一のコロンは最後の行の '11:11'ですか? – Kaz

+0

ファイルを作成したユーザーは、各フィールドの引用要件を再分析せずに区切り記号を置き換えることで、フォーマットを破棄しました。 "X"で区切られた値ファイルの区切り文字を無意味に変更すると情報が破壊され、この種の曖昧さが生じます。 (これはあなたを助けません、私は知っていますが、将来のための教訓です。誰かがファイルを壊した場合、あなたは合法的に不平を言うことができます。) – rici

答えて

2

あなたはawkを使用してsubtrlengthでいくつかの文字列操作を行うことができますパイプ|に出力フィールドセパレーターOFSを設定

awk 'BEGIN{OFS="|"}{col1=substr($0,1,length($0)-12);col2=substr($0,length($0)-10, 10);print col1,col2}' yourfile 

を。それはsubstr()length()を使用して2つの列を区切ります。列1は、文字1から始まり、レコードの終わりの12文字で終わることで見つけられます。列2は、レコードの最後の10文字を開始し、10文字をつかむことで検出されます。

テスト出力:

$ awk 'BEGIN{OFS="|"}{col1=substr($0,1,length($0)-12);col2=substr($0,length($0)-10, 10);print col1,col2}' test 
!J INC|0001438823 
#1 A LIFESAFER HOLDINGS, INC.|0001509607 
#1 ARIZONA DISCOUNT PROPERTIES LLC|0001457512 
#1 PAINTBALL CORP|0001433777 
$ LLC|0001427189 
& S MEDIA GROUP LLC|0001447162 
&TV COMMUNICATIONS INC.|0001479357 
'MKTG, INC.'|0000886475 
11:11 CAPITAL CORP.|0001463262 

これだけ作品2番目のフィールドは常に10桁の数字のように見えるので。それはファイルの他の部分で変化した場合は、別のルートを移動する必要があります。

2

あなたが後方

$ rev file | sed 's/:/~/3' | rev | column -ts: 

!J INC        0001438823 
#1 A LIFESAFER HOLDINGS, INC.  0001509607 
#1 ARIZONA DISCOUNT PROPERTIES LLC 0001457512 
#1 PAINTBALL CORP     0001433777 
$ LLC        0001427189 
& S MEDIA GROUP LLC     0001447162 
&TV COMMUNICATIONS INC.    0001479357 
'MKTG, INC.'      0000886475 
11~11 CAPITAL CORP.     0001463262 

2列があることを知ってから、それに近づくことができる、私たちはラインを逆にして~:の3番目のインスタンスを置き換えます。

交換する必要が2つ以上ある場合は、サフィックスの代わりにg3を使用してください。 TXR

1

考えられる解決策:

戦略は、データ間を一致させることですが、線で右に左に逆転しました。そのため、我々はlazily mappingreverse機能により(get-lines)の出力によって生成されるラインの遅延:list@(next ...)を用いて入力し、リダイレクト。以下はfixcolon.txrです:

@(next :list @[mapcar* reverse (get-lines)]) 
@(repeat) 
@ (assert) 
@ (cases) 
:@right:'@left' 
@ (or) 
:@right:@left 
@ (end) 
@ (do (put-line (reverse 
        (if (break-str left ":") 
        `:@right:'@left'` 
        `:@right:@left`)))) 
@(end) 

は、基本的には唯一の2つのケースがあります。我々は、左か、我々にはない引用されたシングルを持っています。我々は、彼らが存在している場合は、単一引用符を削除し、フィールドがコロンが含まれている場合にのみ、それらを再instateたいです。

次の余分な行がデータに追加されました:

11:11 CA:PI:TAL CORP.:0001463262: 

出力:

$ txr fixcolon.txr < data 
!J INC:0001438823: 
#1 A LIFESAFER HOLDINGS, INC.:0001509607: 
#1 ARIZONA DISCOUNT PROPERTIES LLC:0001457512: 
#1 PAINTBALL CORP:0001433777: 
$ LLC:0001427189: 
& S MEDIA GROUP LLC:0001447162: 
&TV COMMUNICATIONS INC.:0001479357: 
MKTG, INC.:0000886475: 
'11:11 CAPITAL CORP.':0001463262: 
'11:11 CA:PI:TAL CORP.':0001463262: 

余計な引用はMKTG, INC.の周りになくなっています。引用は、11:11 ...フィールドの周りに導入されています。 (サンプルデータと質問テキストは、要件を指定していないか、または暗示していないため、埋め込まれた単一引用符を処理する試みは行われません)。

@(assert)は、次のケースと一致しないデータを除いて、パターンマッチングが確実に爆発するようにします。この指針は効果的に「私の後のすべてが一致するか、そうでなければスローする」と述べています。これがなければ、@(repeat)ディレクティブは一致しないデータをスキップします。 (:gap 0を使用してスキップしないように指示された場合は、最初の不一致行で停止します。この問題を検出するには、EOFにあるという主張が必要です。

$ txr fixcolon.txr 
foo:bar: 
junk! 
[Ctrl-D][Enter] 
foo:bar: 
txr: unhandled exception of type assert: 
txr: (fixcolon.txr:3) assertion (at var:2) 
txr: during evaluation at fixcolon.txr:3 of form (assert)