共通キーワードに基づいてデータを形式で解析します。

共通キーワードに基づいてデータを形式で解析します。

.mp4xyz で終わる長いファイル名のリストがあります。

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

同じ名前を共有するすべてのイメージを組み合わせて、出力をこの形式に変換する必要があります。この例ではdogimage.mp4andだけを使用していますが、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:54s:4バイトでもありません。)

キーワード(語彙)に基づいて配列リストを並べ替えるには、ループのksort($a);前にを挿入しますforeach。これにより、for配列は語彙的に配列の前に来るため、catsfor配列の前に表示されます。dogimagecatsdogimage

あるいは、次のように、どの配列がどのキーに対応するかについての情報を失わないように、連想配列全体を直列化することもできます。

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減算)で入力され、行の最初のカンマ区切りフィールドから取得された値を持ちます。

外部ハッシュは順序付けされていないため、出力行の順序は保証されません。

関連情報