如何在 bash 脚本的环境变量中存储 grep 的 --exclude 参数

问题描述 投票:0回答:3

我的目标是在文件层次结构中搜索某些文本模式,排除某些文件名模式,然后递归地将匹配的文件复制到名为

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
没有显示任何错误)?

谢谢。

linux bash scripting environment-variables
3个回答
3
投票

大括号扩展非常适合交互式使用,但如果您正在编写脚本,只需使用编辑器快速复制必要的

--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
投票

我知道这会引起皱眉,但这可以通过使用

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
}

0
投票

我想在这里指出,最近的 gnu

grep
版本不支持使用环境变量来保存默认参数。 (我天真地尝试
export GREP="-d skip"
看看这是否能在默认情况下抑制目录。)

来自 https://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html

grep 2.20 及更早版本的 GREP_OPTIONS 环境变量为 no 不再受支持,因为它在编写可移植脚本时会引起问题。 要对 grep 的工作方式进行任意更改,您可以使用别名或 脚本代替。例如,...

© www.soinside.com 2019 - 2024. All rights reserved.