我的目标是在文件层次结构中搜索某些文本模式,排除某些文件名模式,并以递归方式将匹配文件复制到名为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;
}
但是,排除模式可能需要频繁更新,可能需要与其他函数共享,因此我更喜欢将它们全部放在脚本开头声明的变量中。当我执行以下操作时,应排除的文件将复制到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
没有显示任何错误)?
感谢。
答案 0 :(得分:3)
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
的空分隔输出的目的。
答案 1 :(得分:1)
我知道这会引起皱眉但是这可以通过使用eval
来解决,并且由于我们在--exclude=
参数中使用模式,它可能没有通常的风险。
#!/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
}