我有一长串文件名,全部以 .mp4xyz 结尾
12334,dogimage.mp4001
12335,dogimage.mp4002
12336,dogimage.mp4003
12347,cats.mp4001
12348,cats.mp4002
我需要将输出转换为这种格式,结合所有共享相同名称的图像。在此示例中,我仅使用dogimage.mp4
andcats.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
以关键字为关键字,而内部匿名散列以后缀的数值(减一)为关键字,并且具有从该行的第一个逗号分隔字段中获取的值。
请注意,外部哈希未排序,因此无法保证输出行的顺序。