Chinaunix

标题: 求助用sed或awk进行文件替换 [打印本页]

作者: legone2008    时间: 2014-04-16 16:47
标题: 求助用sed或awk进行文件替换
输入:
参数1: Insufficient free space in the %s  directory. The free space is only %s. At least %s is required.
参数2: /export/home
参数3: 5%
参数4: 20%

输出: Insufficient free space in the /export/home directory. The free space is only 5%. At least 20% is required.

简单描述:
给出一个源串,如:Insufficient free space in the %s  directory. The free space is only %s. At least %s is required.
把其中%s替换为指定的字符串,如:/export/home,  5%, %20
可以保证%s出现的个数与指定要替换的字符串个数相同, 但指定要替换的字符串个数是不定的,同时要替换的字符串内容也不定。

本想用awk接收外部参数(指定要替换的字符串), 然后以%s作为分隔符,在每个域后面加上指定的字符串,但不知道如何将不定参数传入到awk中。

也考虑过用sed循环替换其中的%s, 但是由于 指定的参数内容不确定,可能就包括了sed指定的分隔符。

有没有较好的替换方式,求大神指点。
作者: Herowinter    时间: 2014-04-16 16:47
本帖最后由 Herowinter 于 2014-04-16 17:54 编辑

回复 1# legone2008
  1. #!/bin/bash

  2. s=$1
  3. for((i=2;i<=$#;i++));do
  4.     s=$(awk -vt=${!i} '{sub("%s",t);print}'<<<$s)
  5. done
  6. echo -e "\n****After repalcement****\n"
  7. echo $s
复制代码
  1. ./print.sh "Insufficient free space in the %s  directory. The free space is only %s. At least %s is required." "/export/#home" "5%" "20%"

  2. ****After repalcement****

  3. Insufficient free space in the /export/#home directory. The free space is only 5%. At least 20% is required.
复制代码

作者: laliheyi    时间: 2014-04-16 16:50
回复 1# legone2008


    printf "Insufficient free space in the %s  directory. The free space is only %s. At least %s is required." /export/home 5% 20%
作者: huang6894    时间: 2014-04-16 17:04
  1. => awk -va='/export/home' -vb='5%' -vc='20%' 'BEGIN{print  "Insufficient free space in the "a" directory. The free space is only "b". At least "c" is required."}'
  2. Insufficient free space in the /export/home directory. The free space is only 5%. At least 20% is required.
复制代码
可以吗?
作者: ly5066113    时间: 2014-04-16 17:13
回复 1# legone2008

try:
  1. $ cat test.sh
  2. #! /bin/bash

  3. n=1
  4. for i in "$@"
  5. do
  6.         if [ $n -eq 1 ]
  7.         then
  8.                 str=$i
  9.         else
  10.                 str=$(echo $str | sed "s#%s#$i#")
  11.         fi

  12.         let n=n+1
  13. done
  14. echo $str
  15. $
  16. $ test.sh 'Insufficient free space in the %s  directory. The free space is only %s. At least %s is required.' /export/home 5% 20%
  17. Insufficient free space in the /export/home directory. The free space is only 5%. At least 20% is required.
复制代码

作者: legone2008    时间: 2014-04-16 17:27
楼上几位都没有认真看要求。
@2楼,3楼: 参数个数不定,参数值不定  
@4楼: 如果参数中包含#,sed就会出错, 如:/export/#home
作者: laliheyi    时间: 2014-04-16 17:30
回复 5# legone2008


    参数个数定不定有关系吗?参数数量与%s数量一致就足够了,有多少写多少
作者: ly5066113    时间: 2014-04-17 08:31
回复 5# legone2008


用2楼的方法吧,最简单:
  1. $ cat test.sh
  2. #! /bin/bash

  3. str=printf
  4. for i in "$@"
  5. do
  6.         str="$str '$i'"
  7. done
  8. eval $str
  9. $
  10. $ test.sh 'Insufficient free space in the %s  directory. The free space is only %s. At least %s is required.' /export/home 5% 20%
  11. Insufficient free space in the /export/home directory. The free space is only 5%. At least 20% is required.
复制代码

作者: Herowinter    时间: 2014-04-17 09:50
回复 8# ly5066113
学习了,sed或awk确实绕弯了,
应该直接printf的。


   
作者: rulebook    时间: 2014-04-17 11:06
  1. #!/bin/sh
  2. [ "$1" == "" ] && echo "$1 is Null" && exit

  3. [ `echo $(($#-1))` != `echo $1 | egrep -o "%s" | wc -l` ] && echo "\%s the wrong number!" && exit

  4. eval echo $(echo $1 | awk '{for(i=1;i<='`echo $[$#-1]`';i++){sub(/%s/,"$"i+1)}}1')
复制代码

作者: legone2008    时间: 2014-04-17 11:14
本帖最后由 legone2008 于 2014-04-17 11:22 编辑

printf是格式化输出,这个我也考虑过。
由于输入得的参数,除了已知%s确定为要替换的字符串外,其他值是不确定的,比如参数1中出现%80,%%%,这个时候printf就要出错了。目前7楼的答案是最适合的。
作者: laliheyi    时间: 2014-04-17 11:34
回复 11# legone2008


    难道说参数1不是你控制的,是随机出现的?
作者: blackold    时间: 2014-04-19 22:14
本帖最后由 blackold 于 2014-04-19 22:22 编辑

回复 1# legone2008


Try

test.sh
  1. #!/bin/sh
  2. tmpfile=$.tmp
  3. for i in "$@";do echo -E "$i" >> $tmpfile;done
  4. awk 'NR==1{split($0,a,/%s/);printf a[1];next}{printf "%s%s",$0,a[NR]}END{print ""}' $tmpfile
  5. rm $tmfile
复制代码
  1. ./test.sh arg1 arg2 arg3
复制代码

作者: jeffreyst    时间: 2014-04-21 14:56
本帖最后由 jeffreyst 于 2014-04-21 15:02 编辑

cat temp
nsufficient free space in the %s  directory. The free space is only %s. At least %s is required.

cat test.sh
  1. #! /bin/bash

  2. cat temp  | sed 's/%s/\n\n/g' | awk -va="$1" -vb="$2" -vc="$3" '
  3. {if(NR==2)
  4.         {
  5.                 print a
  6.         }
  7.         else
  8.         {
  9.                 if(NR==4)
  10.                 {
  11.                         print b
  12.                 }
  13.                 else
  14.                 {
  15.                         if(NR==6)
  16.                         {
  17.                                 print c
  18.                         }
  19.                         else{
  20.                                 print $0
  21.                         }
  22.                 }
  23.         }
  24. }'| sed ':1;N;s/\n//;t1'
复制代码
./test.sh /export/home %50 %10
nsufficient free space in the /export/home  directory. The free space is only %50. At least %10 is required.
这种方法好像可以实现,但是有点复杂,应该可以再优化下...




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