.mp4xyz で終わる長いファイル名のリストがあります。
12334,dogimage.mp4001
12335,dogimage.mp4002
12336,dogimage.mp4003
12347,cats.mp4001
12348,cats.mp4002
同じ名前を共有するすべてのイメージを組み合わせて、出力をこの形式に変換する必要があります。この例ではdogimage.mp4
andだけを使用していますが、cats.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
出力形式ですPHPserialize()
だから:
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";}
(この文字列の長さは5バイトでもs:5
4s:4
バイトでもありません。)
キーワード(語彙)に基づいて配列リストを並べ替えるには、ループのksort($a);
前にを挿入しますforeach
。これにより、for配列は語彙的に配列の前に来るため、cats
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でハッシュハッシュを使用する1つの方法は次のとおりです。
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
、内部匿名ハッシュはサフィックスの数値(1減算)で入力され、行の最初のカンマ区切りフィールドから取得された値を持ちます。
外部ハッシュは順序付けされていないため、出力行の順序は保証されません。