我想遍历以“。”开头的文件。在目录 x 中(x 可能是任何路径):
$ for file in x/.*
> do
> echo -n $file" "
> done
x/. x/.. x/..a x/.b
摆脱 x/. 和 x/.. 的最佳方法是什么?
使用 bash,您可以使用GLOBIGNORE
$ ls -1tra
..
.test1
.test
test
.
$ for i in .*; do echo $i;done
.
..
.test
.test1
$ GLOBIGNORE=".:.."
$ for i in .*; do echo $i;done
.test
.test1
使用 pattern .{[^.]*,.?*}
,这意味着任何以.
非 a 字符.
开头的名称,或以..
字符开头的名称。
此外,您应该用"$file"
引号括起来,这样带空格的名称就不会被分开。
正如另一位指出的那样,ls -A不包括 . 和..从列表中,不确定它有多标准。
您还可以使用find:
find . -mindepth 1 -maxdepth 1 -name '.*'
一个只有通配符的解决方案,因此您不必为命令替换和引用而烦恼:
.!(.|)
这需要设置 extglob shell 选项:
shopt -s extglob
这可能很明显,但该!()
构造意味着除了列出的模式之一(由 分隔|
)之外的任何内容。
for file in x/.*; do echo "$file "; done | grep -v "x/\.\{1,2\} $" | tr -d '\n'
$file
前后$
的空间grep
很重要。它确保您在列表之间有空格,并且所有内容都不会被弄乱。
或更笼统地说
for file in somedir/.*; do echo "$file "; done | grep -v "\w/\.\{1,2\} $" | tr -d '\n'
在 Mac OS X 上使用ls -A
。查看手册页以获取本地选项的实现。这个命令
ls -A | grep '^\.'
把你要找的名单给我。
(1) 使用 2 种模式: $ echo x/.??* x/.[^.] - 还有其他组合。如果使用不同的,请确保它会捕获“...”和“.a”
(2) 使用 GLOBIGNORE 并排除 2 个条目:$ GLOBIGNORE='*/.:*/..'; 回声 x/.*
(3) 将 dotglob 与 GLOBIGNORE 一起使用。这将自动排除 . 和..,但现在你必须排除“所有其他”: $ shopt -s dotglob; GLOBIGNORE='*/[^.]*'; 回声 x/*
对于 x/.{[^.],.?}* 中的文件
这将匹配例如 .a .zoo.17 ... ..0 ..hello
但不会匹配。.. 文件不以点开头
打破它...
{a,b} 进行交替,首先匹配 a,然后匹配 b。所以我们也可以像这样写上面的:
对于 x/.[^.]* x/..?* 中的文件
所以让我们检查第一个: .[^.]* [^.] 是一个倒置字符类——没有克拉 ^ 它只会匹配一个点;^ 将其反转,因此它将匹配除点以外的任何字符。之后是一个星号,它将匹配 0 个或更多任何类型的字符因此此模式 .[^.]* 将匹配名称以 - 开头的文件。- 至少有两个字符长 - 第二个字符不是。从上面的例子中,它匹配: .a .zoo.17
现在让我们检查第二个: ..?* ?匹配任何字符(但不是 0 个字符)。我们对星星很熟悉。所以这个模式 ..?* 将匹配名称以 .. 开头的文件,长度至少为三个字符 从上面的示例中,它匹配: ... ..0 ..hello
由于交替的工作方式,第一组中的文件都将首先匹配——它们不会与第二组中的文件进行比较。
另一种选择是保持通配简单并明确删除不需要的路径:
for file in x/.* ; do
[[ $file == */. || $file == */.. ]] && continue
echo -n "$file "
done