gpt4 book ai didi

linux - ls | grep 变量作为正则表达式

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:22:34 25 4
gpt4 key购买 nike

我正在编写一个 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 should not be used in this manner , 和 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

关于linux - ls | grep 变量作为正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37868835/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com