1

我有一个大的 .csv 文件要处理,我的元素是这样随机排列的:

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

其中字段LOCAL、、REMOTE或显示如下:MLOCALMREMOTE

  1. 当它们成对显示时 ( LOCAL / REMOTE ) 如果第 3 个字段是MLOCAL第 4 个字段是MREMOTE,则第 5第 7 个字段表示 的值和日期MLOCAL第 6第 8 个表示的值和日期MREMOTE
  2. 当它们显示为单个(仅LOCAL或仅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_limitand是and orLOCAL_limit之间的减法结果)VOLUME_ALOCATEDMLOCAL_VALUELOCAL_VALUE

因此,在我的输出文件中,字段位置应排列如下: 第 4 个字段= MLOCAL_VALUE第 5 个字段= MLOCAL_TIMESTMP第 7 个字段= LOCAL_VALUE第 8 个字段= LOCAL_TIMESTAMP第 10 个字段= MREMOTE_VALUE第 11 个字段= MREMOTE_TIMESTAMP第 12 个字段= REMOTE_VALUE第 13 个字段=REMOTE_TIMESTAMP

现在,一个例子是这样的:对于以下输入:name, ID, VOLUME_ALLOCATED, MLOCAL, MREMOTE, 33222, 56, 22/10/2012,18/10/2012

name, ID, VOLUME_ALLOCATED, REMOTE, 234455,19/12/2012

我应该处理这一行,输出应该是这样的:

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

7th, 8th, 9th, 12th, 和13th字段为空,因为没有与以下内容相关的信息:LOCAL_VALUE, LOCAL_TIMESTAMP, LOCAL_limit, REMOTE_VALUE, 和REMOTE_TIMESTAMP

或者

name, ID, VOLUME_ALLOCATED, , , , , , , , , 234455,9/12/2012

4th, 5th, 6th, 7th, 8th, 9th,10th和 , 11th, 字段应该是空值,因为没有关于:MLOCAL_VALUE, MLOCAL_TIMESTAMP, MLOCAL_LIMIT, LOCAL_VALUE, LOCAL_TIMESTAMP, LOCAL_LIMIT, MREMOTE_VALUE, 的信息MREMOTE_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, LOCAL$ REMOTE, 2347$ 4324, 19/12/2012$18/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 回答