因此,我必须在目录中搜索长度为 3 个字符的文件。这很容易,问题是 3 个字符中至少有一个必须是“B”或“y”。我知道 [By] 可以确保字符是 B 或 ay,但是简单地执行 [By][By][By] 是不够的,因为并不要求所有 3 个字符都是 B 或 y;只要其中一个是就行。请帮忙。
答案1
您可以在 for 循环中进行模式匹配。
for file in ./???; do
[[ -e $file && $file = *[By]* ]] || continue
printf 'Do stuff with <%s>\n' "$file"
done
或者,您可以通过运行来启用扩展 glob shopt -s extglob
。然后,您可以使用类似@([By]??|?[By]?|??[By])
shopt -s extglob
for file in ./@([By]??|?[By]?|??[By]); do
[[ -e $file ]] || continue
printf 'Do stuff with <%s>\n' "$file"
done
无论哪种方式都比涉及更有效率grep
。
如果您正在为 POSIX sh 编写脚本,您可以执行如下操作:
for file in ./???; do
[ -e "$file" ] || continue
case $file in
*[By]*) : ;;
*) continue;;
esac
printf 'Do something with <%s>\n' "$file"
done
最后,您可以使用三个 glob,尽管这会以不同的顺序迭代文件,并且您可能会冒着多次迭代同一个文件的风险。
for file in ./[By]?? ./?[By]? ./??[By]; do
[ -e "$file" ] || continue
printf 'Do something with <%s>\n' "$file"
done
答案2
printf '%s\n' ??? | grep '[By]'
打印printf '%s\n'
传递给它的每个参数,每行一个;是???
一个 glob,它扩展为工作目录中每个三个字符的文件名。它通过管道传输到grep
,它只打印包含您指定的模式的文件名。
顺便说一句,我发现自己用得printf '%s\n'
太多了,~/.bashrc
为了方便输入,我把下面的内容放进了我的:
alias necho='printf "%s\n"' ## newline-echo
大多数情况下,这都没问题:文件名包含换行符时会中断,但实际上这种情况非常罕见(我只在专门测试我的脚本时才见过)。使用以下方法可能可以快速实现一个简单的纯 bash 解决方案:外接球,但您也可以使用find
来解决此问题:
find . -name '???' -a -name '*[By]*'
默认情况下,这将以递归方式执行;如果您不想这样,请使用-maxdepth 1
。
find . -maxdepth 1 -name '???' -a -name '*[By]*'
答案3
尝试以下命令:
cd /path/to/directory
ls | while read file; do if [ ${#file} -eq 3 ]; then echo $file; fi; done | grep '[By]'
或者:
for file in ???; do echo $file; done | grep '[By]'
或者,没有任何循环的变体:
ls | grep -ow '\w\{3\}' | grep '[By]'
ls
将列出当前目录中的所有文件,然后我们只选择长度正好为 3 个字符的文件名,最后,使用grep
,我们只选择包含B
或 的文件名y
。