LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2315|回复: 24

请问如下一段 sed或 awk代码怎么写?对我来说,比较难哦

[复制链接]
发表于 2007-1-19 09:58:07 | 显示全部楼层 |阅读模式
如题,我的目录结构如下:


  1. w_3.9039nm/
  2.           ----->p_2.50e+01kpa/result.txt
  3.                 p_4.00e+01kpa/result.txt
  4.                 p_5.50e+01kpa/result.txt
  5.                 p_7.00e+01kpa/result.txt

  6. w_4.2588nm/
  7.           ----->p_2.50e+01kpa/result.txt
  8.                 p_4.00e+01kpa/result.txt
  9.                 p_5.50e+01kpa/result.txt
  10.                 p_7.00e+01kpa/result.txt
复制代码


其中的result.txt为不同的w和p下的计算数据,格式相同,但数字不同,举例如下:


  1.       rhosa=  0.2879                  drhos=  0.0014
  2.        nksa=  453.44                   dnks=  2.1915
  3.       ucmsa=   14.02                  ducms=  0.0476
  4.       ucfsa=    1.79                  ducfs=  0.0124
  5.       ucpsa=   12.23                  ducps=  0.0519
  6.     dhuffsa=  6.3425 kj/mol         ddhuffs=  0.2167 kj/mol
  7.     dhufpsa=  6.3603 kj/mol         ddhufps=  0.7861 kj/mol
  8.        dhsa= 12.7028 kj/mol            ddhs=  0.9143 kj/mol
  9.       adswt= 11.0945 wt%
  10.      adsmgg=  110.94 mg/g
  11.    adsmmolg=  6.9168 mmol/g
  12.     adsgcm3=  0.1387 g/cm3
  13. adsmmolcm3=  8.6443 mmol/cm3
  14.    fracfill=  0.4065

复制代码


我想提取每个p条件下的数据,以及对应的每个result.txt文件里的第1列变量里adswt的数据,然后输出到一个名为adswt.dat的文件中,其文件格式如下:


  1.                  w,3.9039nm          w,4.2588nm
  2. p,kpa            adswt, wt%          adswt,wt%         
  3. 2.50e+01         xxxxxx              xxxxxx
  4. 4.00e+01         xxxxxx              xxxxxx
  5. 5.50e+01         xxxxxx              xxxxxx
  6. 7.00e+01         xxxxxx              xxxxxx

复制代码


其中的,xxxxxx为各个p和w条件下的result.txt文件里的adswt数据,其值不相同。

请问shell中该如何用awk或者sed命令写该段代码??
发表于 2007-1-19 13:06:35 | 显示全部楼层
试试, 我没试过的.

  1. #!/bin/bash
  2. wdir=(w_*nm)
  3. echo -n >adswt.dat
  4. for ((i=0;i<${#wdir[*]};i++))
  5. do
  6. echo -ne "\t"${wdir[i]/_/,}>>adswt.dat
  7. done
  8. echo >>adswt.dat
  9. echo -ne 'p,kpa'>>adswt.dat
  10. for ((i=0;i<${#wdir[*]};i++))
  11. do
  12. echo -ne '\tadswt,wt%'>>adswt.dat
  13. done
  14. echo >>adswt.dat
  15. cd ${wdir[1]}
  16. pdir=(p_*kpa)
  17. cd ..
  18. for ((i=0;i<${#pdir[*]};i++))
  19. do
  20.         a=$(echo ${pdir[i]}|sed 's/p_\|kpa//g')
  21.         echo -ne "$a">>adswt.txt
  22.         for ((j=0;j<${#wdir[*]};j++))
  23.         do
  24.                 echo -ne "\t">>adswt.txt
  25.                 awk '/adswt/ {print $2}' "${wdir[j]}/${pdir[i]}/result.txt" >>adswt.txt
  26.         done
  27.         echo >> adswt.txt
  28. done
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-1-19 20:14:45 | 显示全部楼层
有点晕了。呵呵。
lz试试看吧:
  1. #!/bin/bash
  2. TITLE="title"
  3. CONTENT="content"
  4. ADSWT="adswt"
  5. wlist=""
  6. echo | awk '{printf("%10-s%10-s"," "," ")}'>$TITLE
  7. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  8. do
  9.         w=`echo $i | sed -n -e 's/_/,/;p'`
  10.         wlist=${wlist}" "$w
  11.         echo $w | awk '{printf("%10-s%10-s",$1," ")}'>>$TITLE;
  12. done
  13. echo | awk '{printf("\n")}'>>$TITLE
  14. echo | awk '{printf("%10-s%10-s","p,kpa"," ")}'>>$TITLE
  15. for i in ${wlist};
  16. do
  17.         echo | awk '{printf("%10-s%10-s","adswt, wt%"," ")}'>>$TITLE
  18. done
  19. echo | awk '{printf("\n")}'>>$TITLE
  20. echo "" > $CONTENT
  21. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  22. do
  23.         w=`echo $i | sed -n -e 's/_/,/;p'`
  24.         for j in `find ./$i -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f3 | uniq`;
  25.         do
  26.                 p=`echo $j | cut -d'_' -f2 | sed -n -e 's/kpa//;p'`
  27.                 a=`cat ./$i/$j/result.txt | grep "adswt" | awk '{print $2}'`
  28.                 line=`grep $p $CONTENT|cut -d' ' -f1`
  29.                 if [ "$line" = "$p" ]
  30.                 then
  31.                         awk '{if($1 != pinfo) print $0}' pinfo=$p ${CONTENT} >> ${CONTENT}.t
  32.                         awk '{if($1 == pinfo) printf("%s%10-s%10-s",$0," ",ainfo)}' pinfo=$p ainfo=$a ${CONTENT} >> ${CONTENT}.t
  33.                         mv -f ${CONTENT}.t ${CONTENT}
  34.                 else
  35.                         echo $p | awk '{printf("\n%10-s%10-s",$1," ")}' >> $CONTENT
  36.                         echo $a | awk '{printf("%10-s",$1)}' >> $CONTENT
  37.                 fi
  38.         done
  39. done
  40. echo | awk '{printf("\n")}' >> $CONTENT
  41. cat $TITLE $CONTENT > $ADSWT
  42. rm $CONTENT $TITLE
  43. cat $ADSWT
复制代码

俺机器上的结果(w_4.2588nm目录下没有p=2.50e+01的子目录)
adswt的数值都是我自己瞎写的。
~/programming/ksh/example1$ mysh
                    w,3.9039nm          w,4.2588nm         
p,kpa               adswt, wt%          adswt, wt%         


2.50e+01            08.0945   
4.00e+01            09.0945             11.0945   
5.50e+01            10.0945             12.0945
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-1-19 21:16:53 | 显示全部楼层
能否把如下输出的结果 做成code输出

w,3.9039nm w,4.2588nm
p,kpa adswt, wt% adswt, wt%


2.50e+01 08.0945
4.00e+01 09.0945 11.0945
5.50e+01 10.0945 12.0945


那样我才能看出真正是否对齐了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-1-19 21:27:44 | 显示全部楼层
Post by peter_huang
有点晕了。呵呵。
lz试试看吧:


  1. #!/bin/bash

  2. TITLE="title"
  3. CONTENT="content"
  4. ADSWT="adswt"

  5. wlist=""

  6. echo | awk '{printf("%10-s%10-s"," "," ")}'>$TITLE
  7. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  8. do
  9.         w=`echo $i | sed -n -e 's/_/,/;p'`
  10.         wlist=${wlist}" "$w
  11.         echo $w | awk '{printf("%10-s%10-s",$1," ")}'>>$TITLE;
  12. done
  13. echo | awk '{printf("\n")}'>>$TITLE

  14. echo | awk '{printf("%10-s%10-s","p,kpa"," ")}'>>$TITLE
  15. for i in ${wlist};
  16. do
  17.         echo | awk '{printf("%10-s%10-s","adswt, wt%"," ")}'>>$TITLE
  18. done
  19. echo | awk '{printf("\n")}'>>$TITLE

  20. echo "" > $CONTENT
  21. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  22. do
  23.         w=`echo $i | sed -n -e 's/_/,/;p'`
  24.         for j in `find ./$i -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f3 | uniq`;
  25.         do
  26.                 p=`echo $j | cut -d'_' -f2 | sed -n -e 's/kpa//;p'`
  27.                 a=`cat ./$i/$j/result.txt | grep "adswt" | awk '{print $2}'`

  28.                 line=`grep $p $CONTENT|cut -d' ' -f1`
  29.                 if [ "$line" = "$p" ]
  30.                 then
  31.                         awk '{if($1 != pinfo) print $0}' pinfo=$p ${CONTENT} >> ${CONTENT}.t
  32.                         awk '{if($1 == pinfo) printf("%s%10-s%10-s",$0," ",ainfo)}' pinfo=$p ainfo=$a ${CONTENT} >> ${CONTENT}.t
  33.                         mv -f ${CONTENT}.t ${CONTENT}
  34.                 else
  35.                         echo $p | awk '{printf("\n%10-s%10-s",$1," ")}' >> $CONTENT
  36.                         echo $a | awk '{printf("%10-s",$1)}' >> $CONTENT
  37.                 fi
  38.         done
  39. done

  40. echo | awk '{printf("\n")}' >> $CONTENT

  41. cat $TITLE $CONTENT > $ADSWT
  42. rm $CONTENT $TITLE

  43. cat $ADSWT
复制代码


俺机器上的结果(w_4.2588nm目录下没有p=2.50e+01的子目录)
adswt的数值都是我自己瞎写的。
~/programming/ksh/example1$ mysh
                    w,3.9039nm          w,4.2588nm         
p,kpa               adswt, wt%          adswt, wt%         


2.50e+01            08.0945   
4.00e+01            09.0945             11.0945   
5.50e+01            10.0945             12.0945



  1. echo | awk '{printf("%10-s%10-s"," "," ")}'>$TITLE
复制代码

这段代码不太好吧,因为实际上我是有14个w目录和40个p目录,你这样做就只能输出2个w,最好将w设置成变量,然后做个循环打印TITLE。
回复 支持 反对

使用道具 举报

发表于 2007-1-19 22:15:18 | 显示全部楼层
呵呵,请仔细分析一下,echo | awk '{printf("%10-s%10-s"," "," ")}'>$TITLE
这个只是打一个最初的开头。
打印w是在这里:
  1. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  2. do
  3.         w=`echo $i | sed -n -e 's/_/,/;p'`
  4.         wlist=${wlist}" "$w
  5.         echo $w | awk '{printf("%10-s%10-s",$1," ")}'>>$TITLE;
  6. done
  7. echo | awk '{printf("\n")}'>>$TITLE
复制代码


我机器上的输出:
  1.                     w,3.9039nm          w,4.2588nm         
  2. p,kpa               adswt, wt%          adswt, wt%         
  3. 2.50e+01            08.0945   
  4. 4.00e+01            09.0945             11.0945   
  5. 5.50e+01            10.0945             12.0945
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-1-19 23:26:45 | 显示全部楼层
echo | awk '{printf("%10-s%10-s"," "," ")}'>$TITLE

这句是什么意思?执行出来是什么结果?

还有,%10-s还是 %-10s啊 ??
回复 支持 反对

使用道具 举报

发表于 2007-1-19 23:35:27 | 显示全部楼层
果然有点小问题, 文件名前后用的不一样, 格式也不是很合要求
改了一下.

  1. #!/bin/bash
  2. exec >adswt.dat
  3. wdir=(w_*nm)
  4. printf '%20s' " "
  5. for ((i=0;i<${#wdir[*]};i++))
  6. do
  7. printf '%-20s' ${wdir[i]/_/,}
  8. done
  9. echo
  10. printf '%-20s' 'p,kpa'
  11. for ((i=0;i<${#wdir[*]};i++))
  12. do
  13. printf '%-20s' 'adswt,wt%'
  14. done
  15. echo
  16. pdir=($(ls w_*nm|sed '/^w_.*:$/d'|sort -u))
  17. for ((i=0;i<${#pdir[*]};i++))
  18. do
  19.     a=$(echo ${pdir[i]}|sed 's/p_\|kpa//g')
  20.     printf '%-20s' "$a"
  21.     for ((j=0;j<${#wdir[*]};j++))
  22.     do
  23.         if [ -f "${wdir[j]}/${pdir[i]}/result.txt" ]
  24.         then
  25.             awk '/adswt/ {printf("%-20s",$2)}' "${wdir[j]}/${pdir[i]}/result.txt"
  26.         else
  27.             printf "%-20s" " "
  28.         fi
  29.     done
  30.     echo
  31. done
复制代码

应该没问题, 考虑并不是所有的w目录里的p目录都一样多时测试效果:

  1.                     w,3.2nm             w,3.3nm
  2. p,kpa               adswt,wt%           adswt,wt%
  3. 2.3e+01             11.0945             13.0945
  4. 2.4e+01             12.0945             14.0945
  5. 2.5e+01                                 18.0945
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-1-20 11:25:00 | 显示全部楼层
发现俺的也有问题,这题真不好做。
如果w目录下的p目录数量不一致,很容易出错。

改了一下:
  1. #!/bin/bash
  2. TITLE="title"
  3. CONTENT="content"
  4. ADSWT="adswt"
  5. NA="-------"
  6. wlist=""
  7. echo | awk '{printf("%10-s%10-s"," "," ")}'>$TITLE
  8. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  9. do
  10.         w=`echo $i | sed -n -e 's/_/,/;p'`
  11.         wlist=${wlist}" "$w
  12.         echo $w | awk '{printf("%10-s%10-s",$1," ")}'>>$TITLE;
  13. done
  14. echo | awk '{printf("\n")}'>>$TITLE
  15. echo | awk '{printf("%10-s%10-s","p,kpa"," ")}'>>$TITLE
  16. for i in ${wlist};
  17. do
  18.         echo | awk '{printf("%10-s%10-s","adswt, wt%"," ")}'>>$TITLE
  19. done
  20. echo | awk '{printf("\n")}'>>$TITLE
  21. echo "" > $CONTENT
  22. counter=0
  23. for i in `find . -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f2 | uniq`;
  24. do
  25.         counter=`expr $counter + 1`
  26.         for j in `find ./$i -name "result.txt" -exec dirname "{}" \; | cut -d'/' -f3 | uniq`;
  27.         do
  28.                 p=`echo $j | cut -d'_' -f2 | sed -n -e 's/kpa//;p'`
  29.                 a=`cat ./$i/$j/result.txt | grep "adswt" | awk '{print $2}'`
  30.                 line=`grep $p $CONTENT|cut -d' ' -f1`
  31.                 if [ "$line" = "$p" ]
  32.                 then
  33.                         awk '
  34.                         {
  35.                                 if($1 == pinfo) {
  36.                                         y=0
  37.                                         printf("%s",$0)
  38.                                         if(NF == winfo)
  39.                                                 printf("%10-s"," ")
  40.                                         else
  41.                                                 for(x=NF;x<=winfo+1;x++) {
  42.                                                         if(y%2==0)
  43.                                                                 printf("%10-s"," ")
  44.                                                         else
  45.                                                                 printf("%10-s",na)
  46.                                                         y++
  47.                                                 }
  48.                                         printf("%10-s\n",ainfo);
  49.                                 }
  50.                                 else
  51.                                         printf("%s\n",$0)
  52.                         }' pinfo=$p ainfo=$a winfo=$counter na=$NA ${CONTENT} >> ${CONTENT}.t
  53.                         mv -f ${CONTENT}.t ${CONTENT}
  54.                 else
  55.                         echo | awk '{printf("\n%10-s",pinfo)}' pinfo=$p >> ${CONTENT}
  56.                         grep $p ${CONTENT} | awk '
  57.                         {
  58.                                 y=0
  59.                                 if(NF == winfo)
  60.                                         printf("%10-s"," ")
  61.                                 else
  62.                                         for(x=NF;x<=winfo+1;x++) {
  63.                                                 if(y%2==0)
  64.                                                         printf("%10-s"," ")
  65.                                                 else
  66.                                                         printf("%10-s",na)
  67.                                                 y++
  68.                                         }
  69.                                 printf("%10-s",ainfo)
  70.                         }' ainfo=$a winfo=$counter na=$NA >> ${CONTENT}
  71.                 fi
  72.         done
  73. done
  74. echo | awk '{printf("\n")}' >> $CONTENT
  75. cat $TITLE $CONTENT > $ADSWT
  76. rm $CONTENT $TITLE
  77. cat $ADSWT
复制代码

俺的目录结构如下:
  1. |-----w_3.9039nm
  2. |     |-----p_2.50e+01kpa
  3. |     |     |-----result.txt
  4. |     |-----p_5.50e+01kpa
  5. |     |     |-----result.txt
  6. |-----readme
  7. |-----mysh
  8. |-----w_4.2588nm
  9. |     |-----p_4.00e+01kpa
  10. |     |     |-----result.txt
  11. |     |-----p_5.50e+01kpa
  12. |     |     |-----result.txt
  13. |-----w_5.8079nm
  14. |     |-----p_2.50e+01kpa
  15. |     |     |-----result.txt
  16. |     |-----p_5.50e+01kpa
  17. |     |     |-----result.txt
  18. |-----w_6.7903nm
  19. |     |-----p_4.00e+01kpa
  20. |     |     |-----result.txt
  21. |-----adswt
复制代码

最后的输出如下:
  1.                     w,3.9039nm          w,4.2588nm          w,5.8079nm          w,6.7903nm         
  2. p,kpa               adswt, wt%          adswt, wt%          adswt, wt%          adswt, wt%         
  3. 2.50e+01            08.0945             -------             13.0945   
  4. 5.50e+01            10.0945             12.0945             14.0945   
  5. 4.00e+01            -------             11.0945             -------             15.0945
复制代码

如果lz不需要结果中那些个-------,那么一个简单的sed就可以了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-1-22 10:41:55 | 显示全部楼层
我的代码如下:


  1.     10      ROOT_DIRECTORY=/export/home/pengx/testsh
  2.     11      WORK_DIRECTORY=$ROOT_DIRECTORY/work
  3.     12      TASKS_DIRECTORY=$ROOT_DIRECTORY/tasks
  4.     13      RESULTS_DIRECTORY=$ROOT_DIRECTORY/results
  5.     14  
  6.     15      PORE_WIDTH_DIRECTORY=(0.3549 0.7098)
  7.     16  
  8.     17      PRESSURE_DIRECTORY=(1.00e-08 2.50e-08 5.00e-08)
  9.     18  
  10.     19      RESULT_FILES=(rho nk ucm ucf ucp dh dhuff dhufp adswt adsmgg adsmmolg adsgcm3 adsmmolcm3 fracfill)


  11.     99      echo -ne "Processing final data ........................\t"
  12.    100      cd $RESULTS_DIRECTORY
  13.    101      x=0
  14.    102      for i in ${RESULT_FILES[@]}
  15.    103      do
  16.    104          if [ -f ${i}.txt ]; then
  17.    105              mv ${i}.txt _${i}.old
  18.    106          fi
  19.    107          touch ${i}.txt
  20.    108          printf "%-20s" " " >> ${i}.txt
  21.    109          for j in ${PORE_WIDTH_DIRECTORY[@]}
  22.    110          do
  23.    111              printf "%-20s" "w,${j}nm" >> ${i}.txt
  24.    112          done
  25.    113          printf "\n" >> ${i}.txt
  26.    114          printf "%-20s" "p,kpa" >> ${i}.txt
  27.    115          x=`expr $x+1`
  28.    116          for j in ${PORE_WIDTH_DIRECTORY[@]}
  29.    117          do
  30.    118              for k in ${PRESSURE_DIRECTORY[@]}
  31.    119              do
  32.    120                  while [ $x -lt 6 ]
  33.    121                  do
  34.    122                      printf "%-20s" "${i}" >> ${i}.txt
  35.    123                  done
  36.    124                  while [ $x -ge 6 -a $x -lt 14 ]
  37.    125                  do
  38.    126                      a=`cat $WORK_DIRECTORY/w_${j}nm/p_${k}kpa/result.dat | grep "${i}" | awk '{print $3}'`
  39.    127                      printf "%-20s" "${i}," "$a" >> ${i}.txt
  40.    128                  done
  41.    129                  while [ $x -eq 14 ]
  42.    130                  do
  43.    131                      printf  "%-20s" "${i}" >> ${i}.txt
  44.    132                  done
  45.    133              done
  46.    134          done
  47.    135          printf "\n" >> ${i}.txt
  48.    136          for j in ${PORE_WIDTH_DIRECTORY[@]}
  49.    137          do
  50.    138              for k in ${PRESSURE_DIRECTORY[@]}
  51.    139              do
  52.    140                  printf "%-20s\n" "${k}" >> ${i}.txt
  53.    141              done
  54.    142              for k in ${PRESSURE_DIRECTORY[@]}
  55.    143              do
  56.    144                  a=`cat $WORK_DIRECTORY/w_${j}nm/p_${k}kpa/result.dat | grep "${i}" | awk '{print $2}'`
  57.    145                  printf "%-20s" "$a" >> ${i}.txt
  58.    146              done
  59.    147          done
  60.    148          printf "\n" >> ${i}.txt
  61.    149      done
  62.    150      echo "Done."
复制代码


结果执行时,出现如下的错误:
./test.sh: line 120: [: 0+1: integer expression expected
./test.sh: line 124: [: 0+1: integer expression expected
./test.sh: line 129: [: 0+1: integer expression expected

请问是什么意思?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表