如何存储 – 在bash脚本的环境variables中排除grep的参数

我的目标是search某些文本模式的文件层次结构,排除某些文件名模式,并recursion地将匹配的文件复制到名为confs的本地目录中。 以下脚本完成这项工作:

 #!/bin/bash export FEXCLUDE="{*edit,*debug,*orig,*BAK,*bak,*fcs,*NOPE,*tomcat,*full.xml,*-ha.xml}"; export SRCDIR=/opt/jboss-as-7.1.1.Final/standalone; confshow() { for ii in `grep -rlZ \ --exclude={*edit,*debug,*orig,*BAK,*bak,*fcs,*NOPE,*tomcat,*full.xml,*-ha.xml} \ --exclude-dir={log,tmp,i2b2.war,*.log,*_history,*.old} "<datasource\|username\|password\|user-name" \ $SRCDIR/* | xargs -0 ls {}` ; do cp --parents $ii confs; done; } 

但是,排除模式可能需要频繁更新,可能需要与其他函数共享,所以我更愿意将它们全部放在脚本开头声明的variables中。 当我执行以下操作时,应该排除的文件将被复制到confs目录中:

 #!/bin/bash export FEXCLUDE="{*edit,*debug,*orig,*BAK,*bak,*fcs,*NOPE,*tomcat,*full.xml,*-ha.xml}"; export SRCDIR=/opt/jboss-as-7.1.1.Final/standalone; confshow() { for ii in `grep -rlZ \ --exclude=$FEXCLUDE \ --exclude-dir={log,tmp,i2b2.war,*.log,*_history,*.old} "<datasource\|username\|password\|user-name" \ $SRCDIR/* | xargs -0 ls {}` ; do cp --parents $ii confs; done; } 

任何想法如何获得所需的行为? 或者如何看到grep看到什么时候通过$FEXCLUDE参数( echo不显示任何错误)?

谢谢。

我知道这会引起皱眉,但这可以通过使用eval来解决,而且它可能不会带来通常的风险,因为我们在--exclude=参数中使用了pattern。

 #!/bin/bash fexclude='{*edit,*debug,*orig,*BAK,*bak,*fcs,*NOPE,*tomcat,*full.xml,*-ha.xml}' dexclude='{log,tmp,i2b2.war,*.log,*_history,*.old}' srcdir=/opt/jboss-as-7.1.1.Final/standalone confshow() { eval grep -rlZ \ --exclude="$fexclude" \ --exclude-dir="$dexclude" \ "<datasource\|username\|password\|user-name" \ $srcdir/* | xargs -0 -I {} cp --parents '{}' confs done } 

Brace扩展对于交互式的使用是很好的,但是如果你正在编写一个脚本,只需使用你的编辑器来快速复制必要的--exclude选项并将它们存储在一个数组中。 正如您可能已经注意到的那样,参数展开不会进行大括号扩展。

 #!/bin/bash # You didn't need to export these anyway, since only your script uses them FEXCLUDE=( --exclude '*edit' --exclude '*debug' # etc ) DEXCLUDE=( --exclude-dir log --exclude-dir tmp # etc ) SRCDIR=/opt/jboss-as-7.1.1.Final/standalone confshow() { while IFS= read -d'' -r ii; do cp --parents "$ii" confs done < <( grep -rlZ "${FEXCLUDE[@]}" "${DEXCLUDE[@]}" "<datasource\|username\|password\|user-name" $SRCDIR/* ) 

另外,使用ls破坏了从grep使用空分隔输出的目的。