引用符内の桁数に基づいてデータを解析する

引用符内の桁数に基づいてデータを解析する

現在、現在の形式で大量のデータがあります:

a:7:{i:0;s:4:"9999";i:1;s:4:"10000";i:2;s:4:"10001";i:3;s:4:"10002";i:4;s:4:"10003";i:5;s:4:"10004";i:6;s:4:"989";}

""それらの前の数字にはが付いていますs:4。3 桁の数字の場合は に変更しs:3、5 桁の数字の場合は に変更しますs:5

変換されたデータは次のようになります。

a:7:{i:0;s:4:"9999";i:1;s:5:"10000";i:2;s:5:"10001";i:3;s:5:"10002";i:4;s:5:"10003";i:5;s:5:"10004";i:6;s:3:"989";}

各データ文字{}列は、data.txt

答え1

いかがでしょうか

perl -pe 's/s:\d+:"(.*?)"/sprintf("s:%d:\"%s\"",length($1),$1)/ge'

元。

$ echo 'a:7:{i:0;s:4:"9999";i:1;s:4:"10000";i:2;s:4:"10001";i:3;s:4:"10002";i:4;s:4:"10003";i:5;s:4:"10004";i:6;s:4:"989";}' | 
    perl -pe 's/s:\d+:"(.*?)"/sprintf("s:%d:\"%s\"",length($1),$1)/ge'
a:7:{i:0;s:4:"9999";i:1;s:5:"10000";i:2;s:5:"10001";i:3;s:5:"10002";i:4;s:5:"10003";i:5;s:5:"10004";i:6;s:3:"989";}

追加する-iと、ファイル上でその場で置換を実行できます。

答え2

#!/usr/bin/env bash

IFS=';'

while read LINE
do

        set -- $LINE

        while [ "$1" ]
        do
                if [[ $1 =~ ^s:[0-9]+:\".*\"$ ]]; then
                        s=${1##*:}
                        printf 's:%d:%s%s' $((${#s}-2)) "$s" "$IFS"
                else
                        printf '%s%s' "$1" "$IFS"
                fi
                shift

        done
        printf '\n'

done < data.txt

このスクリプトは、フィールド区切り文字をセミコロン文字に設定し、 の行を反復処理してdata.txt、各行をセミコロン区切り文字で個別のフィールドに分割します。 で始まるフィールド(とs:###:"..."の任意の値) の場合、スクリプトは引用符で囲まれた文字列の長さを計算し、その長さの値を使用してフィールドを再フォーマットし、末尾にフィールド区切り文字を追加します。形式に一致しないフィールドは、そのまま出力され、末尾にフィールド区切り文字が再度追加されます。###...s:###:"..."

a:7:{i:0;s:4:"9999";i:1;s:5:"10000";i:2;s:5:"10001";i:3;s:5:"10002";i:4;s:5:"10003";i:5;s:5:"10004";i:6;s:3:"989";};

関連情報