![根據引號中的位數解析數據](https://rvso.com/image/154465/%E6%A0%B9%E6%93%9A%E5%BC%95%E8%99%9F%E4%B8%AD%E7%9A%84%E4%BD%8D%E6%95%B8%E8%A7%A3%E6%9E%90%E6%95%B8%E6%93%9A.png)
我目前有大量當前格式的數據:
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";};