Tenho uma grande quantidade de dados atualmente no formato atual:
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";}
Os números ""
antes deles têm s:4
. Para números com 3 dígitos, isso deve ser alterado para s:3
e dígitos com 5 dígitos devem ser alterados s:5
e assim por diante.
Os dados convertidos devem ficar assim:
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";}
Cada string de dados {}
está em sua própria linhadata.txt
Responder1
Que tal
perl -pe 's/s:\d+:"(.*?)"/sprintf("s:%d:\"%s\"",length($1),$1)/ge'
Ex.
$ 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";}
Você pode adicionar -i
para realizar a substituição no arquivo no local.
Responder2
#!/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
Este script define o separador de campo para o caractere de ponto e vírgula e, em seguida, itera pelas linhas de data.txt
, dividindo cada linha em campos separados no delimitador de ponto e vírgula. Para campos que começam com s:###:"..."
(para valores arbitrários de ###
e ...
), o script calcula o comprimento da string entre aspas e reformata o campo usando esse valor de comprimento e adicionando um separador de campo à direita. Os campos que não correspondem ao formulário s:###:"..."
são gerados literalmente, adicionando novamente o separador de campo final.
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";};