Bash中多条件路径名扩展:合并元音开头通配符与非数字倒数位条件实现问询
解答你的两个问题
1. 合并元音开头的通配符表达式
当然可以合并!bash的文件名通配符(globbing)支持用**方括号[]**来匹配一组字符,你可以把所有元音字母(大小写)都放在方括号里,再结合??*来保证文件名长度至少3个字符。
最终合并后的通配符是:
[aeiouyAEIOUY]??*
解释一下:
[aeiouyAEIOUY]:匹配任意一个元音字母(包括大小写的a/e/i/o/u/y)作为文件名的第一个字符??*:表示后面至少跟着2个任意字符(??是两个任意字符,*是0个或更多),这样整个文件名的长度就至少是1+2=3,刚好满足你“文件名长度至少3个字符”的要求
所以原来的长串通配符可以直接替换成这个,简洁多了。
2. 实现“倒数第二个字符不是数字”的筛选
用正则表达式配合grep是最直接的方式,因为单纯的文件名通配符很难处理“倒数第N个字符”的反向条件。具体步骤是:
- 先用通配符筛选出元音开头且长度≥3的文件
- 再通过
grep -v反向过滤掉“倒数第二个字符是数字”的文件
完整的命令如下:
MYFILES=$(ls -d [aeiouyAEIOUY]??* | grep -vE '.*[0-9].$') echo "$MYFILES"
解释细节:
ls -d:只列出目录/文件名,不会递归(避免如果有同名目录的话展开内容)grep -vE:-v表示反向匹配(输出不满足正则的内容),-E启用扩展正则表达式.*[0-9].$:这个正则匹配的是倒数第二个字符是数字的文件名:.*:匹配任意长度的前缀[0-9]:匹配一个数字(也就是倒数第二个字符).$:匹配最后一个任意字符,并且到行尾(保证数字在倒数第二的位置)
这样过滤后,剩下的就是符合所有三个条件的文件:albtmk、axxxxx,正好是你想要的结果。
另外提醒一下:尽量避免用ls的输出直接赋值给变量(尤其是文件名包含空格的情况),如果要更健壮的写法,可以用数组来存储文件:
files=([aeiouyAEIOUY]??*) filtered_files=() for file in "${files[@]}"; do if [[ ! "$file" =~ .*[0-9].$ ]]; then filtered_files+=("$file") fi done echo "${filtered_files[@]}"
这种写法不需要调用grep,纯bash内置语法,处理带空格的文件名也没问题。
内容的提问来源于stack exchange,提问作者vojtam
相关产品推荐
相关产品推荐

