私はスキームについて何も知らないので、おそらくsedではなくawkでこれを行うでしょう。
[ghoti@pc ~]$ cat data.txt
1,{},344.233
1,{2},344.197
2,{16},290.281
2,{18},289.093
3,{1},220.896
[ghoti@pc ~]$ cat doit.awk
#!/usr/bin/awk -f
BEGIN {
FS=",";
last1=1;
}
$1 != last1 {
printf("(define v%.0f '(%.0f %s))\n", last1, last1, substr(sect,2));
last1=$1; sect="";
}
{
gsub(/[^0-9]/,"",$2);
sect=sprintf("%s ((%s) %s)", sect, $2, $3);
}
END {
printf("(define v%.0f '(%.0f %s))\n", last1, last1, substr(sect,2));
}
[ghoti@pc ~]$ ./doit.awk data.txt
(define v1 '(1 (() 344.233) ((2) 344.197)))
(define v2 '(2 ((16) 290.281) ((18) 289.093)))
(define v3 '(3 ((1) 220.896)))
[ghoti@pc ~]$
それは確かにもっときつく書くことができます、しかしこれは仕事を成し遂げます。
更新:(コメントごと)
[ghoti@pc ~]$ tail -1 data.txt
3,{1,3,4},220.896
[ghoti@pc ~]$ diff -u doit.awk doitnew.awk
--- doit.awk 2012-05-30 00:38:34.549680376 -0400
+++ doitnew.awk 2012-05-30 00:38:52.893810815 -0400
@@ -10,8 +10,15 @@
last1=$1; sect="";
}
+$2 !~ /}$/ {
+ while ($2 !~ /}$/) {
+ pos=match($0, /,[0-9,]+}/);
+ $0=substr($0, 0, pos-1) " " substr($0, pos+1);
+ }
+}
+
{
- gsub(/[^0-9]/,"",$2);
+ gsub(/[^0-9 ]/,"",$2);
sect=sprintf("%s ((%s) %s)", sect, $2, $3);
}
[ghoti@pc ~]$ ./doitnew.awk data.txt
(define v1 '(1 (() 344.233) ((2) 344.197)))
(define v2 '(2 ((16) 290.281) ((18) 289.093)))
(define v3 '(3 ((1 3 4) 220.896)))
[ghoti@pc ~]$
何が起きてる?
追加する新しいブロックで、2番目のフィールドがで終わるかどうかをテストします}
。そうでない場合は、ループするまでループします。ループを実行するたびに、の前のコンマを削除}
して、スペースに置き換えます。
時々、ブルートフォースが機能します。:-P