使用通配符和隐藏文件进行Bash for循环

six*_*ude 22 bash scripting loops wildcard

只是想要一个简单的shell脚本,有点困惑:

这是我的脚本:

% for f in $FILES; do echo "Processing $f file.."; done
Run Code Online (Sandbox Code Playgroud)

命令:

ls -la | grep bash 
Run Code Online (Sandbox Code Playgroud)

生产:

% ls -a | grep bash
.bash_from_cshrc
.bash_history
.bash_profile
.bashrc
Run Code Online (Sandbox Code Playgroud)

什么时候

FILES=".bash*"
Run Code Online (Sandbox Code Playgroud)

我得到与ls -a相同的结果(不同的格式).但是什么时候

FILES="*bash*"
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

Processing *bash* file..
Run Code Online (Sandbox Code Playgroud)

这不是预期的产出,而不是我的预期.我不允许在文件名的开头加一张外卡吗?是个 .在文件名的开头"特别"莫名其妙?

设置

FILES="bash*"
Run Code Online (Sandbox Code Playgroud)

也行不通.

nos*_*nos 47

bash中的默认通配符不包括以a开头的文件名.(又名隐藏文件).

你可以改变它

shopt -s dotglob

$ ls -a
.  ..  .a  .b  .c  d  e  f
$ ls *
d  e  f
$ shopt -s dotglob
$ ls *
.a  .b  .c  d  e  f
$ 
Run Code Online (Sandbox Code Playgroud)

要再次禁用它,请运行shopt -u dotglob.


gho*_*g74 12

如果你想隐藏和非隐藏,设置dotglob(bash)

#!/bin/bash
shopt -s dotglob
for file in *
do
 echo "$file"
done
Run Code Online (Sandbox Code Playgroud)


ala*_*anc 10

是的,.前面的是特殊的,并且通常不会被*通配符匹配,如bash手册页中所述(并且对于大多数Unix shell来说是通用的):

当模式用于路径名扩展时,除非设置了shell选项dotglob,否则必须明确匹配名称开头或紧跟斜杠后面的字符"." .匹配路径名时,必须始终明确匹配斜杠字符.在其他情况下,"."字符不会被特别处理.


gre*_*eth 7

FILES=".bash*" 因为隐藏文件名以a开头而起作用 .

FILES="bash*"不工作,因为隐藏文件名以开头.不是b

FILES="*bash*"不起作用,因为*字符串开头的通配符省略了隐藏文件.

  • 所以,如果我想这样做,我应该做FILES =".*bash*"?但是如果我想隐藏而不是隐藏文件怎么办? (7认同)

tri*_*eee 5

如果要包含隐藏文件,可以指定两个通配符;一个用于隐藏文件,另一个用于其他文件。

for f in .[!.]* *; do
    echo "Processing $f file.."
done
Run Code Online (Sandbox Code Playgroud)

通配符.*将扩展到所有点文件,但包括您通常希望排除的父目录;so.[!.]*匹配第一个字符是点但第二个字符不是的所有文件。

如果您还有其他带有两个前导点的文件,则需要指定第三个通配符来覆盖这些文件,但排除父目录!尝试..?*要求第二个点之后至少有一个字符。