我有一些变量存储正则表达式,然后我想在本地文件夹中找到与该正则表达式匹配的文件
基本上,我具有要连接的文件名及其扩展名的正则表达式,然后在ereg中使用它们来搜索文件
因此,下面是一个示例:
declare -r CPMOVE_REGEX="^cpmove-[a-z][a-z0-9]{0,16}"
declare -r TAR_REGEX=".tar$"
然后在脚本中的某处执行以下操作。
for b in $(ls -1 | egrep "$CPMOVE_REGEX$TAR_REGEX");
do
backups+=($b);
done
让我们假设备份变量在之前的某个位置声明。
我知道$CPMOVE_REGEX$TAR_REGEX
是错的,我想知道如何正确地做它。
答案 0 :(得分:0)
使其有效的方法之一是将var放在大括号中:“ $ {CPMOVE_REGEX} $ {TAR_REGEX}”
实际上,我是在发布此消息之前找到它的,但是我对测试文件的命名不正确,因此它们与正则表达式不匹配。所以,这就是问题所在。
感谢Micha Wiedenmann提供了答案的链接
答案 1 :(得分:0)
您的正则表达式的问题不在扩展部分($ TAR_REGEX)中,而在第一部分中。尝试回显整个字符串$ CPMOVE_REGEX $ TAR_REGEX并在命令行上进行一些测试。 regexp正常后,将其放入脚本中。 毫无疑问,将两个变量组合为一个字符串,并将其用作egrep参数,如本示例所示:
root@localhost ~ $ declare -r P1='^[0-9]+\-.{3}'
root@localhost ~ $ ls | egrep "$P1"
20190315-GO2.sql
root@localhost ~ $ declare -r P2='.sql$'
root@localhost ~ $ ls | egrep "$P1$P2"
20190315-GO2.sql
root@localhost ~ $
答案 2 :(得分:0)
如何正确使用它。
大概是这样:
declare -r CPMOVE_REGEX="cpmove-[a-z][a-z0-9]{0,16}"
declare -r TAR_REGEX=".tar"
IFS= readarray -d '' -t backups < <(find . -regextype posix-egrep -regex ".*/$CPMOVE_REGEX$TAR_REGEX" -print0)
bashv4之前的-d ''
没有readarray
选项。如果bash低于v4,则需要一段时间的读取循环:
while IFS= read -r tmp; do
backups+=("$tmp")
done < <(find . -regextype posix-egrep -regex ".*/$CPMOVE_REGEX$TAR_REGEX" -print0)
但是由于您的文件名中没有空格,因此您可以使用正则表达式进行过滤,因此,如果您只对没有目录路径的文件名感兴趣,则可以阅读换行符分隔的列表。只有在您确定文件名中永远不会包含任何换行符的情况下。
IFS=$'\n' read -r -a backups < <(find . -regextype posix-egrep -regex ".*/$CPMOVE_REGEX$TAR_REGEX" -print "%f\n")
或
IFS=$'\n' backups=($(find . -regextype posix-egrep -regex ".*/$CPMOVE_REGEX$TAR_REGEX" -print "%f\n"))
注意:
ls
输出。它不是在脚本中使用的工具。 ls
用于在控制台中进行漂亮的打印。使用find
。 Why you shouldn't parse the output of ls(1)。忘记脚本中的ls
。for i in $( .. )
容易出错,$(...)
会进行单词拆分。尽管我认为您的脚本很安全,但是可以使用grep -x -E "<expression without whitespaces>"
,但从概念上讲,使用while读取循环仍然更好。 How can I read a file (data stream, variable) line-by-line (and/or field-by-field)? egrep
已过时,请参见man page。请改用grep -E
。backups+=($b)
做backups+=("$b")
。当您仅引用所有$
扩展时,您将省去很多麻烦。 bashfaq quotes