bash中是否有任何方法可以匹配那样的模式
[0-9]{8}.*.jpg
我已经为以下模式匹配编写了上述内容 “前八个字符应为数字,其余部分为任意内容,以.jpg结尾” 但上述情况无效。如果我以下面的方式写作它正在工作
[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].*.jpg
现在假设我想要前20个字符必须是数字我应该重复[0-9] 20次..我认为有一个更好的解决方案,我不知道......
如果有人知道请帮助....
答案 0 :(得分:3)
您可以在find
中使用正则表达式:
find test -regextype posix-extended -regex "^[0-9]{8}.*.jpg$"
$ touch test/12345678aaa.jpg
$ touch test/1234567aaa.jpg
$ find test -regextype posix-extended -regex ".*/[0-9]{8}.*"
test/12345678aaa.jpg
如果它与previous question相关,您可以使用:
for file in $(find test -regextype posix-extended -regex ".*/[0-9]{8}.*")
do
echo "my file is $file"
done
如果您在其中创建目录和文件,则可能会出现更多匹配项:
$ mkdir test/123456789.dir
$ touch test/123456789.dir/1234567890.jpg
您可以按-type f
进行过滤,以便获取文件:
$ find test -type f -regextype posix-extended -regex ".*/[0-9]{8}.*"
test/12345678aaa.jpg
test/123456789.dir/1234567890.jpg
和/或指定find
的深度,以便它不包含子目录:
$ find test -maxdepth 1 -type f -regextype posix-extended -regex ".*/[0-9]{8}.*"
test/12345678aaa.jpg
答案 1 :(得分:2)
看起来您正在尝试从正则表达式生成文件名列表。你可以这样做,但据我所知,不是直接来自Bash。相反,请使用find
:
find -E . -regex '.*/[0-9]{8}.*\.jpg' -depth 1
类似的东西适用于我的Mac OS X系统;在Linux上,当前目录的.
是可选的,或者您可以指定要搜索的其他目录。我添加了-depth 1
以避免降级到子目录。
答案 2 :(得分:1)
有点迟到的答案。
Bash的文件名扩展模式(称为 globbing )拥有自己的规则。它们以两种形式存在:
shopts -s extglob
您可以阅读有关规则的详细信息,例如here。 (3.5.8.1模式匹配)
你应该记住,通配规则不是传统的正则表达式(你可能知道grep
或sed
等),特别是它们是不是perl的(扩展的)正则表达式。
因此,如果你想使用文件名扩展(也称为globbing),你就会遇到上述两个(简单/扩展)模式规则。当然,bash知道正则表达式,但不用于文件名扩展(通配)。
所以,你可以做下一个:
shopt -s globstar #if you haven't already enabled - for the ** expansion
regex="[0-9]{8}.*\.jpg"
for file in ./**/*.jpg #will match all *.jpg recusrively (globstar)
do
#try the regex matching
[[ $file =~ $regex ]] || continue #didn't match
#matched! - do something with the file
echo "the $file has at least 8 digits"
done
或者您可以使用带有内置正则表达式匹配规则的find
命令(请参阅其他答案),或使用类似perl的正则表达式的grep
,例如:
find somewhere -type f -name \*.jpg -maxdepth 1 -print0 | grep -zP '/\d{8}.*.jpg'
速度:对于大树,find
更快。至少在我的笔记本上,其中:
while IFS= read -d $'\0' -r file
do
echo "$file"
done < <(find ~/Pictures -name \*.JPG -print0 | grep -zP 'P\d{4}.*\.JPG')
运行real 0m1.593s
和
regex="P[0-9]{4}.*\.JPG"
for file in ~/Pictures/**/*.JPG
do
[[ $file =~ $regex ]] || continue #didn't match
echo "$file"
done
运行real 0m3.628s
秒。
在小树上,恕我直言最好使用构建bash正则表达式。 (也许,我更喜欢它,因为我喜欢./**/*.ext
扩展,并且在变量中正确获取所有文件名,无论空格等,而不关心-print0
和read -d $'\0;
等...)