web-dev-qa-db-ja.com

ファイルが複数行に分割される単一のレコード

Informaticaからの変換後、フラットテキストファイルを使用してteradataテーブルに格納しています。このファイルには14個のフィールドが含まれています(〜区切り)。しかし、レコードが複数の行に散らばっているため、informaticaはそれを取得できません。

Sed/awkまたはその他のコマンドを使用して区切り文字をカウントすることでレコードを結合する方法はありますか?

サンプルレコード---

48602040112~4100010080701242015~2010-01-21 10:23:44~Foods~7~Poultry ~Perdue Smart Chicken~Circular~06
-JAN-10~24-JAN-10~$5.99~24 oz., select varieties
up to 4 at this price, additional
Save up to $4.00 
load up on savings~~1598

理想的には次のようになります-

48602040112~4100010080701242015~2010-01-21 10:23:44~Foods~7~Poultry ~ Perdue Smart Chicken~Circular~06-JAN-10~24-JAN-10~$5.99~24 oz., select varieties up to 4 at this price, additional Save up to $4.00 load up on savings~~1598

はっきりしない場合は、改行文字が含まれています。

3
ckp
tr -d \\n <infile | tr \~ \\n | paste -d~ - - - - - - - - - - - - - -

それはうまくいくでしょう。

1
mikeserv

分割フィールドをスペースありとスペースなしのどちらで結合するかを決定する方法は明確ではありません。 _06<NL>-JAN-10_は改行を削除する必要がありますが、_varieties<NL>up to_は改行をスペースに置き換える必要があります。

上記の懸念を無視すると、このプロトタイプのAwkコマンドにたどり着くことができます。

_$ awk 'BEGIN { RS = "~" }
       { gsub(/\n/,"",$0);
         printf("%s", $0);
         if (++i < 14) { printf("~"); }
         else { i = 0; printf("\n"); } }' < in.txt > out.txt
_

_~_でレコードを分割して、各フィールドが実際にレコードになるようにします。次に、各レコードの空白をgsubでトリミングし、フィールド1から13の場合は区切り文字を続けて印刷し、14の場合は改行を続けて印刷します(カウントをリセットします)。

フィールドの数が14で割り切れない場合、出力の最後の行が不完全になり、改行ではなく_~_で終了します。

結合の問題に対処するための可能な方法は、改行をそのままにするか、データに出現しない文字に置き換えることです。後処理ステップとして結合を実行します。 _@_がデータに含まれていないとします。改行を_@_に置き換えると、通常のテキスト処理ツールを使用して簡単なパターン置換を適用できます。たとえば、s/([0-9])@-/\1-/の行に沿った置換は、_06@-JAN_のような壊れた日付を処理します。

このロジックでは、改行の削除が必要な特定のフィールドのデータ型を理解する必要がある場合があります。これにより、たとえば、日付を特別に処理できます。

0
Kaz

sedを使用してみてください:

_sed -rn ':a;/^([^~]*~){13}[^~]*$/!{N;s/\n//;ba};p' yourfile.tsv
_

それが何をするか

スクリプトには、_;_で区切られた3つの部分があります。

  • _:a_は、分岐できるラベルを定義します
  • /^([^~]*~){13}[^~]*$/!{N;s/\n//;ba}は完全な列を検索します
    • /^([^~]*~){13}[^~]*$/は、正確に14フィールド(_~_以外のものが0回以上出現)で、_~_が13回出現する行で区切られた行を検索します。
    • _!_検索結果を反転します(見つからない場合は...)
    • _{N;s/\n//;ba}_列が完了していない場合に実行されるブロック
      • Nは別の行を読み取ります
      • _s/\n//_は、2行の間の改行を削除します
      • baは(b)以前に定義したラベル(a)に分岐します
  • pは列全体を出力します
0
user43791