1

処理する大きな .csv ファイルがあり、要素は次のようにランダムに配置されます。

xxxxxx,xx, MLOCAL, MREMOTE, 33222, 56, xxxxxx,xx, , , , 22/10/2012, xxxxxx,xx, , , xxxxxx,xx, , , xxxxxx,xx , , , , , xxxxxx , xx , , , , xxxxxx , xx, , ,18/10/2012MREMOTEMLOCAL332225622/10/201218/10/2012MLOCAL34199322/10/2012
MREMOTE935682808/10/2012
LOCALREMOTE193161525322/10/201222/10/2012
REMOTELOCAL186587138366622/10/201222/10/2012
REMOTE118030613419/10/2012

フィールドLOCALREMOTEMLOCALまたはMREMOTEは次のように表示されます。

  1. それらがペア ( LOCAL / REMOTE ) として表示される場合、3 番目のフィールドがMLOCALで、4 番目のフィールドがMREMOTEの場合、5 番目7 番目のフィールドは の値と日付を表しMLOCAL6 番目8番目のフィールドは の値と日付を表しますMREMOTE
  2. それらが単一 ( onlyLOCALまたは only REMOTE) として表示される場合、4 番目と 5 番目のフィールドはフィールド 3 の値と日付を表します。

ここで、次を使用してこれらの行を分割しました。

nawk 'BEGIN{

while (getline < "'"$filedata"'")
split($0,ft,",");
name=ft[1];
ID=ft[2]
 ?=ft[3]
 ?=ft[4]
....................

しかし、3 番目と 4 番目のフィールドのパターンが見つからないため、さらに処理するために配列要素のそれぞれに var 名を割り当て続けなければなりません。

ここで、「case」ステートメントを使用しようとしましたが、awk または nawk では機能しません (gawk のみが期待どおりに機能しています)。私もこれを試しました:

if ( ft[3] == "MLOCAL" && ft[4]!= "MREMOTE" )
{
        MLOCAL=ft[3];
        MLOCAL_qty=ft[4];
        MLOCAL_TIMESTAMP=ft[5];
}
else if ( ft[3] == MLOCAL && ft[4] == MREMOTE )
{
        MLOCAL=ft[3];
        MREMOTE=ft[4];
        MOCAL_qty=ft[5];
        MREMOTE_qty=ft[6];
        MOCAL_TIMESTAMP=ft[7];
        MREMOTE_TIMESTAMP=ft[8];
}
else if ( ft[3] == MREMOTE && ft[4] != MOCAL )
{
        MREMOTE=ft[3];
        MREMOTE_qty=ft[4];
        MREMOTE_TIMESTAMP=ft[5];
..........................................

しかし、それはうまくいきません。

ですから、これをどのように処理するかについて何か考えがある場合は、考えられるすべての状況を上からカバーするためのパターンを見つけることができるように、ヒントを教えていただければ幸いです。

編集

このすべての助けに感謝する方法がわかりません。さて、私がしなければならないことは、上で書いたよりも複雑です。できる限り簡単に説明しようと思います。そうしないと、皆さんをかなり混乱させるでしょう。私の出力は次のようになります。

NAME, UNIQUE_ID, VOLUME_ALOCATED, MLOCAL_VALUE, MLOCAL_TIMESTMP, MLOCAL_limit, LOCAL_VALUE, LOCAL_TIMESTAMP, LOCAL_limit, MREMOTE_VALUE, MREMOTE_TIMESTAMP_ REMOTE_VALUE_REMOTE_TIMESTAMP

(ここでMLOCAL_limit、 とはとまたはLOCAL_limitの間の減算結果です)VOLUME_ALOCATEDMLOCAL_VALUELOCAL_VALUE

したがって、私の出力ファイルでは、フィールド位置ように配置 する必要あります。MLOCAL_VALUEMLOCAL_TIMESTMPLOCAL_VALUELOCAL_TIMESTAMPMREMOTE_VALUEMREMOTE_TIMESTAMPREMOTE_VALUEREMOTE_TIMESTAMP

ここで、例は次のようになります: 次の入力の場合: name, ID, VOLUME_ALLOCATED, MLOCAL, MREMOTE, 33222, 56,22/10/201218/10/2012

nameIDVOLUME_ALLOCATEDREMOTE234455_19/12/2012

この行を処理する必要があり、出力は次のようになります。

name, ID, VOLUME_ALLOCATED, 33222, 22/10/2012, MLOCAL_LIMIT, , , , 56, 18/10/2012_ _

7th8th9th、 、およびに関する情報がないため、 、 、 12th、 およびフィールドは空です: 、、、および13thLOCAL_VALUELOCAL_TIMESTAMPLOCAL_limitREMOTE_VALUEREMOTE_TIMESTAMP

また

name, ID, VOLUME_ALLOCATED, , , , , , , , _ 234455_9/12/2012

4th5th6th7th、 、8th9th10th、、11th、 に関する情報がないため、フィールドは空の値である必要があります: MLOCAL_VALUEMLOCAL_TIMESTAMPMLOCAL_LIMITLOCAL_VALUELOCAL_TIMESTAMPLOCAL_LIMITMREMOTE_VALUEMREMOTE_TIMESTAMP

VOLUME_ALLOCATEDID次のように、スクリプトで以前に処理されたフィールドに基づいて、他の csv ファイル (「info.csv」と呼ばれる) から取得されます。

情報.csv

VOLUME_ALLOCATED, ID, CLIENT 5242881, 64, subscriber 567743, 24_visitor

データ.csv

NAME, 64, MLOCAL, 341993, 23/10/2012 NAME, $ , $ , $ 24_LOCALREMOTE2347432419/12/201218/12/2012

今、私のコードはこれです:

    #! /usr/bin/bash

input="info.csv"
filedata="data.csv"
outfile="out"

nawk 'BEGIN{
while (getline < "'"$input"'")
{
split($0,ft,",");
volume=ft[1];
id=ft[2];
client=ft[3];

key=id;
volumeArr[key]=volume;
clientArr[key]=client;
}
close("'"$input"'");

while (getline < "'"$filedata"'")
{
gsub(/\$/,","); # substitute the $ separator with comma
split($0,ft,",");
volume=volumeArr[id]; # Get the volume from the volumeArr, using "id" as key
segment=clientArr[id]; # Get the client mode from the clientArr, using "id" as key
NAME=ft[1];
id=ft[2];

3 番目と 4 番目のフィールドを処理する方法がわからないため、残りのフィールドを設定する正しい方法が見つかりません。

? =ft[3];
? =ft[4];

かなり混乱させて申し訳ありませんが、これが私の現在の状況です。ありがとう

4

1 に答える 1

7

サンプル入力から期待される出力を提供しませんでしたが、ここでは入力行の 2 つの異なる形式の値を取得する方法を示します。

$ cat tst.awk
BEGIN{ FS=","; OFS="\t" }
{
   delete value       # or use split("",value) if your awk cant delete arrays
   if ($4 ~ /LOCAL|REMOTE/) {
      value[$3] = $5
      date[$3]  = $7
      value[$4] = $6
      date[$4]  = $8
   }
   else {
      value[$3] = $4
      date[$3]  = $5
   }

   print
   for (type in value) {
      printf "%15s%15s%15s\n", type, value[type], date[type]
   }
}
$ awk -f tst.awk file
xxxxxx,xx,MLOCAL,MREMOTE,33222,56,22/10/2012,18/10/2012
        MREMOTE             56     18/10/2012
         MLOCAL          33222     22/10/2012
xxxxxx,xx,MREMOTE,MLOCAL,33222,56,22/10/2012,18/10/2012
        MREMOTE          33222     22/10/2012
         MLOCAL             56     18/10/2012
xxxxxx,xx,MLOCAL,*341993,22/10/2012*
         MLOCAL        *341993    22/10/2012*
xxxxxx,xx,MREMOTE,9356828,08/10/2012
        MREMOTE        9356828     08/10/2012
xxxxxx,xx,LOCAL,REMOTE,19316,15253,22/10/2012,22/10/2012
         REMOTE          15253     22/10/2012
          LOCAL          19316     22/10/2012
xxxxxx,xx,REMOTE,LOCAL,1865871,383666,22/10/2012,22/10/2012
         REMOTE        1865871     22/10/2012
          LOCAL         383666     22/10/2012
xxxxxx,xx,REMOTE,1180306134,19/10/2012
         REMOTE     1180306134     19/10/2012

期待される出力を投稿していただければ、さらにお役に立てます。

于 2013-01-18T06:17:36.493 に答える