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

时间:2010-01-25 21:26:13

标签: bash loops scripting wildcard

只是想要一个简单的shell脚本而且很困惑:

这是我的剧本:

% for f in $FILES; do echo "Processing $f file.."; done

命令:

ls -la | grep bash 

产生

% ls -a | grep bash
.bash_from_cshrc
.bash_history
.bash_profile
.bashrc

何时

FILES=".bash*"

我得到与ls -a相同的结果(不同的格式)。但是当

FILES="*bash*"

我得到了这个输出:

Processing *bash* file..

这不是预期的输出而不是我的预期。我不允许在文件名的开头加一张外卡吗?是个 。在文件名的开头“特别”莫名其妙?

设置

FILES="bash*"

也行不通。

5 个答案:

答案 0 :(得分:45)

bash中的默认globbing不包含以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
$ 

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

答案 1 :(得分:11)

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

#!/bin/bash
shopt -s dotglob
for file in *
do
 echo "$file"
done

答案 2 :(得分:10)

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

  

当模式用于路径名扩展时,字符“。”       在名称的开头或紧随斜线后必须       明确匹配,除非shell选项 dotglob       组。匹配路径名时,斜杠字符必须      总是明确匹配。在其他情况下,“。”      角色没有特别对待。

答案 3 :(得分:7)

FILES=".bash*"有效,因为隐藏文件名称以.

开头

FILES="bash*"不起作用,因为隐藏文件名称以.而不是b

开头

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

答案 4 :(得分:1)

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

for f in .[!.]* *; do
    echo "Processing $f file.."
done

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

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