Chinaunix

标题: 练习题(键值循环替换) [打印本页]

作者: yestreenstars    时间: 2014-04-14 11:48
标题: 练习题(键值循环替换)
本帖最后由 yestreenstars 于 2014-04-14 14:31 编辑

处理前:
ABC = A1_B1;
ABD = C1_D1;
A1 = D0_A0;
B1 = A1_ABD;
C1 = C0;
D1 = B0_C1;

处理后:
ABC = D0_A0_D0_A0_C0_B0_C0;
ABD = C0_B0_C0;
A1 = D0_A0;
B1 = D0_A0_C0_B0_C0;
C1 = C0;
D1 = B0_C0;

处理要求:
将“值”中所有能替换的“键”都替换为对应的“值”。

请各位先尝试独立思考,贴出自己的代码,为避免影响大家的思路,我先将我的代码隐藏起来~

PS:本例子是从Perl版搬运过来的。


作者: reyleon    时间: 2014-04-14 12:19
本帖最后由 reyleon 于 2014-04-14 14:36 编辑


看我大蟒蛇递归处理,
  1. #!/usr/bin/python
  2. import re
  3. d = {}
  4. for r in open('file'):
  5.         s = re.sub(r';$',"",r).split()
  6.         d[s[0]] = s[-1].split("_")
  7. def rec(values,lst):
  8.         for i in values:
  9.                 if i not in d:
  10.                         lst.append(i)
  11.                         continue
  12.                 rec(d[i],lst)
  13.         return lst
  14. for k,v in d.iteritems():
  15.         print '%s = %s' % (k,'_'.join(rec(v,lst=[])))
复制代码

作者: seesea2517    时间: 2014-04-14 13:01
这个太难了,不敢想。
作者: reb00t    时间: 2014-04-14 13:05
围观学习。
作者: libo26_lee    时间: 2014-04-14 13:18
占位~~~~~~~~
作者: 圣西罗门柱    时间: 2014-04-14 13:30
占位~~~~~ 看看牛人的回答
作者: 刺客阿地    时间: 2014-04-14 13:33
围观学习,占位mark个
作者: ly5066113    时间: 2014-04-14 13:50
回复 1# yestreenstars


try:
  1. awk -F '[ =;]+' '
  2. function dsub(s)
  3. {
  4.         n=0
  5.         for(j in a)
  6.                 n+=sub(j,a[j],s)
  7.         if(n)
  8.                 dsub(s)
  9.         else
  10.                 r=s
  11. }
  12. NR==FNR {
  13.         a[$1]=$2
  14.         next
  15. }
  16. {
  17.         dsub($2)
  18.         print $1" = "r";"
  19. }
  20. ' file file
复制代码

作者: dandy1992    时间: 2014-04-14 14:04
强!回复 8# ly5066113


   
作者: haokoo    时间: 2014-04-14 14:22
我想看看星辰的思路。
作者: jason680    时间: 2014-04-14 15:13
回复 1# yestreenstars

$ awk -F' *[=_;] *' 'function x(S, s,t,n,r,b){if(a[S]!="")return x(a[S],s);t=split(S,b," ");if(t==1)return S;r="";for(n=1;n<=t;n++)r=r==""?x(b[n]):r" "x(b[n]);return r}{k[NR]=$1;s="";for(n=2;n<NF;n++)s=s?s" "$n:$n;a[$1]=s}END{for(n=1;n<=NR;n++)a[n]=x(a[k[n]]);for(n=1;n<=NR;n++){gsub(/ /,"_",a[n]);print k[n]" = "a[n]";"}}' FILE
ABC = D0_A0_D0_A0_C0_B0_C0;
ABD = C0_B0_C0;
A1 = D0_A0;
B1 = D0_A0_C0_B0_C0;
C1 = C0;
D1 = B0_C0;

   
作者: blackold    时间: 2014-04-14 16:10
本帖最后由 blackold 于 2014-04-14 16:10 编辑

Can use sed?

  1. sed 'h;s/.*[ =]\+//;:n;'$(sed 's#[ =;]\+#/#g;s#^#s/#;s#$#g#;H;;$!d;g;s/\n/;/g;' urfile)';tn;G;s/\(.*\)\n\([^ =]\+\).*/\2 = \1/' urfile
复制代码
quote from @rdcwayx:
Never do it in 'awk' if 'sed' can handle it;


作者: yestreenstars    时间: 2014-04-14 16:23
回复 12# blackold

牛,学习了~
   
作者: ly5066113    时间: 2014-04-14 16:34
本帖最后由 ly5066113 于 2014-04-14 17:07 编辑

回复 12# blackold


向黑哥学习。
改进版:
  1. sed -r ':a;N;$!ba;h;s/[ ;]//g;x;G;:b;s/(.+)([^=]*;.*\n\1=)(\w+)/\3\2\3/;tb;s/[^;]*$//' file
复制代码

作者: blackold    时间: 2014-04-14 16:50
回复 14# ly5066113


    Tim 老师太谦虚了。

    Lookup-table, 好!!! 我就差这一招没学会
作者: yinyuemi    时间: 2014-04-14 16:56
本帖最后由 yinyuemi 于 2014-04-14 17:01 编辑
  1. awk -F'[ _;]+' 'function f(x,y){for(n in y){if(n in a){f(n,a[n])}else{printf !b[i]++?n:"_"n}}}{for(i=3;i<=NF-1;i++)a[$1][$i]=$i}END{for(i in a){printf i" = ";f(i,a[i]);print ";"}}'
复制代码

作者: 旋转小马    时间: 2014-04-14 17:08
来围观各位大神学习的~~~
作者: rulebook    时间: 2014-04-14 17:25
  1. awk -F"[= ]+" -vm=1 '{gsub(/;/,"",$2);s[$1]=$2} END{while(m==1){m=0;for(i in s){l=split(s[i],p,"_");for(j=1;j<=l;j++){if(p[j] in s){gsub(p[j],s[p[j]],s[i])}};y=split(s[i],u,"_");for(k=1;k<=y;k++){if(u[k] in s){m=1}}}};for(i in s){print i" = "s[i]";"}}' o
复制代码
果断回复学学大神的手法
作者: Herowinter    时间: 2014-04-14 18:32
回复 1# yestreenstars

下班前练个手,请多多指教。
  1. awk '{sub(/;$/,"")} NR==FNR{a[$1]=$3;next} {while($3~/[A-D]1|[A-D][A-D]/){split($3,b,"_");for(i in b)if(b[i] in a){sub(b[i],a[b[i]],$3)}};$0=$0";"}1' i i
  2. ABC = D0_A0_D0_A0_C0_B0_C0;
  3. ABD = C0_B0_C0;
  4. A1 = D0_A0;
  5. B1 = D0_A0_C0_B0_C0;
  6. C1 = C0;
  7. D1 = B0_C0;
复制代码

作者: vic260844    时间: 2014-04-14 18:33
Mark 一下学习
作者: iziang    时间: 2014-04-14 18:42
先占个坑,回头再填
作者: iziang    时间: 2014-04-14 20:27
  1. awk 'NR==FNR{gsub(/;/,"");a[$1]=$3;next} NR!=FNR{do{k=0;for(i in a)if(gsub(i,a[i],$3))k++;}while(k)print;}' sample sample
复制代码

作者: r2007    时间: 2014-04-15 07:03
小明,对就是小明,不小心把原文件删了,怎么用处理结果得到原文件呢?
作者: yestreenstars    时间: 2014-04-15 08:55
回复 23# r2007

逆操作貌似不太现实?
   
作者: yaozhibing41001    时间: 2014-04-15 09:56
本帖最后由 yaozhibing41001 于 2014-04-15 10:57 编辑

回复 2# reyleon

看我大python另一路办法
  1. #! /usr/bin/python
  2. with open(r'C:\Users\Administrator\Desktop\python\d\a.lst','r') as file:
  3.     _A_dict=dict(x.replace('\n','').replace(';','').split(' = ') for x in file.readlines())
  4. for x,y in _A_dict.iteritems():
  5.     a=0
  6.     while a<len(_A_dict[x].split('_')):
  7.         z=_A_dict[x].split('_')
  8.         for bb in z :
  9.             if bb not in _A_dict:
  10.                 a+=1
  11.             else:
  12.                 _A_dict[x]=_A_dict[x].replace(bb,_A_dict[bb])
  13.                 a=0
  14.     print x,'=',_A_dict[x]
复制代码
  1. ABC = D0_A0_D0_A0_C0_B0_C0
  2. ABD = C0_B0_C0
  3. A1 = D0_A0
  4. B1 = D0_A0_C0_B0_C0
  5. C1 = C0
  6. D1 = B0_C0
复制代码

作者: reyleon    时间: 2014-04-15 10:47
回复 25# yaozhibing41001


      你的蟒蛇比我的长的漂亮
作者: rdcwayx    时间: 2014-04-15 12:15
blackold 发表于 2014-04-14 16:10
Can use sed?quote from @rdcwayx:


OMG. V5
作者: sharkww    时间: 2014-04-15 18:05
awk 'BEGIN{FS="[ =;]"}{a[NR]=$1;b[NR]=$4;}END{for(i=1;i<=NR;i++){do{k=0;for(j=1;j<=NR;j++){k+=gsub(a[j],b[j],b[i]);}}while(k>0)}for(i=1;i<=NR;i++){printf "%s = %s;\n" a[1],b[1]}}' sample.file
作者: fengzheyu    时间: 2014-04-16 17:04
大婶们玩一样啊
作者: huxk_cu    时间: 2014-04-16 23:28
我也来凑个热闹
  1. awk -F= 'function f(a,k,v){n=0;split(v,b,"_");
  2.           for(i in b){s=b[i];if(a[s])n+=gsub(s,a[s],v)}if(n)f(a,k,v);else print k"="v}
  3.           {a[$1]=$2}END{for(i in a) f(a,i,a[i])}'
复制代码

作者: yqljb    时间: 2014-04-18 16:53
还是看一下星晨大神的
作者: 大帝亚历山大    时间: 2014-04-21 08:42
占个位。。。看答案的。。
作者: pitonas    时间: 2014-04-21 13:14
还是来看一下答案。
作者: zxy877298415    时间: 2014-04-21 15:50
太高深,目前还写不出来,先看看星辰大的思路学习一下!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2