[英]ls | grep with variable as regex
我正在编写一个bash脚本来自动化一些任务。 我要做的一件事是在目录中的文件名中搜索一个模式,然后遍历结果。
当我运行此脚本时:
data=$(ls $A_PATH_VAR/*.ext | grep -o '201601[0-9]\{2\}\|201602[0-9]\{2\}')
echo $data
我得到了预期的结果-在$A_PATH_VAR/
中扩展名为.ext
的文件名中找到的所有匹配项的列表。 但是,当我将所述模式存储在变量中然后使用时,如下所示:
startmo=201601
endmo=201602
mo=$((startmo+1))
grepstr="'$startmo[0-9]\{2\}"
while [ $mo -le $endmo ]
do
grepstr="$grepstr\|$mo[0-9]\{2\}"
mo=$((mo+1))
done
grepstr="$grepstr'"
echo $grepstr # correct
data=$(ls $A_PATH_VAR/*.ext | grep -o $grepstr)
echo $data
$grepstr
的模式已正确回显-即它包含值'201601[0-9]\\{2\\}\\|201602[0-9]\\{2\\}'
,但$data
为空。 为什么是这样?
我的解决方案:
mo=$((startmo+1))
grepstr="($startmo[0-9][0-9]"
while [ $mo -le $endmo ]
do
grepstr="$grepstr|$mo[0-9][0-9]"
mo=$((mo+1))
done
grepstr="$grepstr)"
files=$(ls $A_PATH_VAR/*.ext)
setopt shwordsplit
for file in $files
do
if [[ $file =~ $grepstr ]]
then
date=$BASH_REMATCH
fi
...
done
在下面的内容中,我忽略了您的输入源是ls
,除了开头的注释外, ls
不应以这种方式使用 ,而应该考虑使用 find
(在GNU扩展形式中包含-regex
运算符) 。
在:
pattern="'pattern'"
grep $pattern
...双引号( "
)是句法的 -它们在解析阶段由shell占用,而其中的单引号是文字的 -外部句法引号指定其中的所有内容都是被视为字符串的一部分(除非解析双引号内容的规则不同)。
因此,当您运行grep $pattern
,将发生以下情况:
$pattern
的内容被分解为IFS中任何字符上的单词。 默认情况下,IFS仅包含空格; 但是,如果您拥有IFS=a
,那么它将被分解为单词"pa
和单词ttern"
pattern
包含"hello * world"
,并且您对IFS进行了默认解析,则我们将把单词分解为"hello
, *
和world"
,然后将*
替换为当前目录中的文件列表。 显然,您不需要这样做。 因此,如果您的目标是防止字符串拆分和glob扩展,请仅使用语法引号:
pattern="pattern"
grep "$pattern"
顺便说一句,如果我有此任务,我可以按如下方式编写它(以避免为每个可能的日期范围手动构建正则表达式):
startmo=201601
endmo=201705
currmo=$startmo
# this requires GNU date
# on MacOS, you can install this via macports and invoke it as gdate
next_month() {
date -d "+1 month ${1:0:4}-${1:4:2}-15" +%Y%m
}
while [[ $currmo <= $endmo ]]; do
currmo=$(next_month "$currmo")
files=( *"$currmo"* )
[[ -e $files ]] || { echo "No files found for month $currmo" >&2; continue; }
printf '%s\n' "${files[@]}"
done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.