根据常见关键字将数据解析为格式

根据常见关键字将数据解析为格式

我有一长串文件名,全部以 .mp4xyz 结尾

12334,dogimage.mp4001
12335,dogimage.mp4002
12336,dogimage.mp4003
12347,cats.mp4001
12348,cats.mp4002

我需要将输出转换为这种格式,结合所有共享相同名称的图像。在此示例中,我仅使用dogimage.mp4andcats.mp4但会有数千个关键字。

a:3:{i:0;s:4:"12334";i:1;s:4:"12335";i:2;s:4:"12336";}
a:2:{i:0;s:4:"12347";i:1;s:4:"12348";}

下面的字符串代表:

a:3& a:2= 图片总数

i:0= 该关键字的图像计数

答案1

呆呆地:

BEGIN{

    # split by , or .mp4
    FS=",|\\.mp4"

    # sort array by numeric value
    PROCINFO["sorted_in"] = "@val_num_asc"
}

# store count in a, store others as key, value pair in d[keyword]
{ a[$2]++; d[$2][$3]= $1 }

END{
    for( keyword in d ){
        printf( "a:%d:{", a[keyword] )
        for( i in d[keyword] )
            printf( "i:%d;s:4:\"%d\";", i-1, d[keyword][i] )
        printf( "}\n" )
    }
}

更新

要保持关键字顺序:

BEGIN {
    # split by , or .mp4
    FS=",|\\.mp4"

    # sort array by numeric value
    PROCINFO["sorted_in"] = "@val_num_asc"
}

{
    # insert next ordered number into loop_order upon new keyword
    if(!($2 in d))
        loop_order[k++] = $2

    # store count in a, store others as key, value pair in d[$2]
    a[$2]++; d[$2][$3]= $1
}

END{
    for (j = 0; j < length(loop_order); ++j) {
        keyword = loop_order[j]
        printf( "a:%d:{", a[keyword] )
        for( i in d[keyword] )
            printf( "i:%d;s:4:\"%d\";", i-1, d[keyword][i] )
        printf( "}\n" )
    }
}

答案2

这就是输出格式php的serialize(), 所以:

php -r '
  while ($line = fgets(STDIN)) {
    $n = strtok($line, ",");
    $image = strtok(".\n");
    $a[$image][] = $n;
  }
  foreach ($a as $v) echo serialize($v) . "\n";' < file.list

根据您的输入,给出:

a:3:{i:0;s:5:"12334";i:1;s:5:"12335";i:2;s:5:"12336";}
a:2:{i:0;s:5:"12347";i:1;s:5:"12348";}

(请注意,s:5而不是s:4因为这些字符串的长度是 5 个字节,而不是 4 个字节)。

要根据关键字(词法)对数组列表进行排序,请在循环ksort($a);之前插入 of foreach,然后数组 forcats将显示在数组 for 之前,dogimage因为在词法cats上位于数组之前dogimage

或者可能序列化整个关联数组,这样您就不会丢失有关哪个数组对应于哪个关键字的信息,例如:

php -r '
  while ($line = fgets(STDIN)) {
    $n = strtok($line, ",");
    $image = strtok(".\n");
    $a[$image][] = $n;
  }
  echo serialize($a) . "\n";' < file.list

这使:

a:2:{s:8:"dogimage";a:3:{i:0;s:5:"12334";i:1;s:5:"12335";i:2;s:5:"12336";}s:4:"cats";a:2:{i:0;s:5:"12347";i:1;s:5:"12348";}}

答案3

这是一种方法 - 在 Perl 中使用 hash-of-hashes:

perl -F, -lne '
  ($k,$i) = split(/\.mp4/, $F[1]); 
  $s{$k}->{$i-1} = $F[0]
  }{
  foreach $k (keys %s) {
    $hr = $s{$k};
    printf "a:%d:{", keys %$hr;
    foreach $i (sort {$a <=> $b} keys %$hr) {
      printf "i:%d;s:4:\"%s\";", $i, $hr->{$i}; 
    }
    printf "}\n";
  }  
' file
a:1:{i:0;s:4:"12334";i:1;s:4:"12335";i:2;s:4:"12336";}
a:0:{i:0;s:4:"12347";i:1;s:4:"12348";}

“外部”散列%s以关键字为关键字,而内部匿名散列以后缀的数值(减一)为关键字,并且具有从该行的第一个逗号分隔字段中获取的值。

请注意,外部哈希未排序,因此无法保证输出行的顺序。

相关内容