2

我遇到的问题与以前的帖子有关。现在我现在拥有的是:

  1. 一个 900 万行的 CSV 文件,其中包含随机排列的字段,例如:

    192.168.12.23,62,LOCAL,341993,23/10/2012
    192.168.12.25,11,MONLOCAL$MONREMOTE,33222$56,22/10/2012$18/10/2012
    192.168.12.678,14,MONLOCAL,341993,22/10/2012
    
    192.168.12.83,18, , ,
    192.168.12.21,49,LOCAL$REMOTE,19316$15253,22/10/2012$22/10/2012
    192.168.12.79,52,REMOTE,1180306134,19/10/2012
    192.168.12.41,44,MONLOCAL$MONREMOTE,1865871$383666,22/10/2012$22/10/2012
    192.168.12.29,23,MONREMOTE,151145,18/10/2012
    

    正如您可能已经观察到的那样,有 2 个字段分隔符,,并且$

    • 字段 1 = IP 地址

    • 字段 2 = 唯一 ID

    • 字段 3 = IP 已使用的连接(例如 LOCAL、REMOTE、MONLOCAL 或 MONREMOTE)

    • 字段 4 = 也可以是 IP 已使用的连接(例如 LOCAL、REMOTE、MONLOCAL 或 MONREMOTE)或与字段 3 相关的值

    • 字段 5 = 如果字段 4 是 LOCAL 或 REMOTE 或 MONLOCAL 或 MONREMOTE,则字段 5 表示字段 3 的值,否则表示与字段 3 相关的时间戳

    • 字段 6 = 如果字段 4 是 LOCAL 或 REMOTE 或 MONLOCAL 或 MONREMOTE,则字段 6 表示字段 4 的值,否则它将不存在。

    • 字段 7 = 如果字段 4 是 LOCAL 或 REMOTE 或 MONLOCAL 或 MONREMOTE,则字段 7 表示字段 3 的时间戳,否则它将不存在。

    • 字段 8 = 如果字段 4 是 LOCAL 或 REMOTE 或 MONLOCAL 或 MONREMOTE,则字段 7 表示字段 4 的时间戳,否则它将不存在。

  2. 我需要处理上面的文件并输出以下格式,字段始终按以下顺序(10 个字段):

    IP,ID,MONLOCAL_value,MONLOCAL_timestamp,LOCAL_value,LOCAL_timestamp,MONREMOTE_value,MONREMOTE_timestamp,REMOTE_value,REMOTE_timestamp 如:

    192.168.12.23,62, , ,341993,23/10/2012, , , , 
    192.168.12.25,11,33222,22/10/2012, , , , ,56,18/10/2012
    192.168.12.678,14,341993,22/10/2012, , , , , ,  
    192.168.12.83,18, , , , , , , , 
    192.168.12.21,49, , ,19316,22/10/2012, , ,15253,22/10/2012
    192.168.12.79,52, , , , , , ,1180306134,19/10/2012
    192.168.12.41,44,1865871,22/10/2012, , ,383666,22/10/2012, , 
    192.168.12.29,23, , , , ,151145,18/10/2012, , 
    
  3. 我有以下脚本来处理上面的文件:

    nawk 'BEGIN {
        while (getline < "'"$data"'" > 0)
        {
        {FS = "[,,$]"; OFS=","}
        split($0,flds)
           {if ($4 ~ /LOCAL|REMOTE|MONLOCAL|MONREMOTE/) {
                if ($3 ~ /MONLOCAL/) {
                        MONREMOTE_time=flds[8];
                        MONREMOTE_value=flds[6];
                        MONLOCAL_time=flds[7];
                        MONLOCAL_value=flds[5]; }
                if ($3 ~ /MONREMOTE/) {
                        MONREMOTE_time=flds[7];
                        MONREMOTE_value=flds[5];
                        REMOTE_value=flds[6];
                        REMOTE_time=flds[8]; }
                if ($3 ~ /REMOTE/) {
                        REMOTE_value=flds[5];
                        REMOTE_time=flds[7];
                        LOCAL_value=flds[6];
                        LOCAL_time=flds[8]; }
        } else {
                if($3 ~ /MONLOCAL/) {
                        MONLOCAL_value=flds[4];
                        MONLOCAL_time=flds[5]; }
                if ($3 ~ /MONREMOTE/) {
                        MONREMOTE_value=flds[4];
                        MONREMOTE_time=flds[5]; }
                if ($3 ~ /LOCAL/) {
                        LOCAL_value=flds[4];
                        LOCAL_time=flds[5]; }
                if ($3 ~ /REMOTE/) {
                        REMOTE_value=flds[4];
                        REMOTE_time=flds[5]; }
        }
      }
      {print MONLOCAL_value",MONLOCAL_time,LOCAL_value,LOCAL_time,MONREMOTE_value,MONREMOTE_time,REMOTE_value,REMOTE_time;}
     }
    }'
    
  4. 这里的坏处是,正如您在下面观察到的那样,输出与预期不符,因为我无法在读取每一行后清除数组值,或者找到一种解决方案来为每行动态地对数组元素充电:

    4915779000211,62, , ,341993,23/10/2012, , , , ,
    4915779000212,11,33222,22/10/2012,341993,23/10/2012,56,18/10/2012, , 
    491639000591,14,341993,22/10/2012,341993,23/10/2012, , , ,  
    491779001768,18,319307448,18/10/2012,19316,22/10/2012,383666,22/10/2012,1180306134,19/10/2012
    4915779000213,49,3849259,05/10/2012,19316,22/10/2012,56,18/10/2012,15253,22/10/2012
    491779000758,52,9356828,08/10/2012,19316,22/10/2012,56,18/10/2012,1180306134,19/10/2012
    4915779000214,44,1865871,22/10/2012,19316,22/10/2012,383666,22/10/2012,1180306134,19/10/2012
    491639000221,23,319307448,18/10/2012,19316,22/10/2012,151145,18/10/2012,1180306134,19/10/2012
    

所以,如果你们知道如何使这个 awk 函数工作并给出预期的输出,我将不胜感激。

4

1 回答 1

1

通过一些修改,您可以使用类似于以下内容的内容:

while read line; do 
  if [[ "$line" == *\$* ]]; then 
    echo $line | awk -F',|\$' '{print $1,$2,$5,$6,$3}' >> newfile;
  else
    echo $line | awk -F',' '{print $1,$2,$3,,$4,,$5}' >> newfile;
  fi
done < "/path/to/your/file"
于 2013-01-23T03:20:50.097 回答