如何对除当前目录和父目录之外的每个隐藏文件进行 glob

les*_*ana 88 command-line shell bash

我想 glob 每个隐藏文件和目录,但不是当前 ( .) 和父目录 ( ..)。

我正在使用 bash。

观察当前行为:

$ ls -a
.  ..  ...a  ...aa  ..a  ..aa  .a  .aa  .aaa  a
$ echo *
a
$ echo .*
. .. ...a ...aa ..a ..aa .a .aa .aaa
Run Code Online (Sandbox Code Playgroud)

我想.*表现得像这样

$ echo .*
...a ...aa ..a ..aa .a .aa .aaa
Run Code Online (Sandbox Code Playgroud)

有外壳选项 dotglob

$ shopt -s dotglob
Run Code Online (Sandbox Code Playgroud)

这在某种程度上起作用;现在我可以使用*glob 的所有内容(隐藏或不隐藏)但不能...

$ echo *
...a ...aa ..a ..aa .a .aa .aaa a
Run Code Online (Sandbox Code Playgroud)

但现在我无法区分隐藏与否。此外,.*仍然 globs...

$ echo .*
. .. ...a ...aa ..a ..aa .a .aa .aaa
Run Code Online (Sandbox Code Playgroud)

有没有办法使.*不扩展到...

Mar*_*erg 77

您可以使用该GLOBIGNORE变量来隐藏...目录。这也会自动设置dotglob选项,因此*现在匹配隐藏和非隐藏文件。dotglob不过,您可以再次手动 unset ,这将提供您想要的行为。

看这个例子:

$ ls -a
.  ..  a  .a  ..a
$ GLOBIGNORE=".:.."
$ shopt -u dotglob
$ echo * # all (only non-hidden)
a
$ echo .* # all (only hidden)
.a ..a
Run Code Online (Sandbox Code Playgroud)

  • 没问题,我不怕批评。只是我不明白评论和我的答案之间的联系。但是因为我也不明白您的答案与至少一致的原始问题之间的联系;) (4认同)
  • 我没有得到这个评论......问题不是关于 ls 命令,而是关于 **glob**——“在命令中包括 glob”正是 OP 想要做的...... (2认同)

buk*_*zor 28

下面的第一个 glob 需要一个前导点和至少一个额外的非点字符。这两个 glob 一起将匹配任何可能的隐藏文件,包括具有多个前导点但不是.或 的文件..,这正是您所要求的。

ls -ld .[!.]* ..?*
Run Code Online (Sandbox Code Playgroud)

  • 这也将排除`..foo`。可移植的语法是`.[!.]*`。`.[^.]*` 不是标准的(虽然很多 shell 都支持) (4认同)

小智 7

你只是在寻找文件吗?你可以使用find吗?

类似于(假设 GNU find):

find . -mindepth 1 -maxdepth 1 -name ".*" -printf "%P\n"
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 7

使用zsh, fishpdksh以及至少它的一些派生词,例如mkshposh

echo .*
Run Code Online (Sandbox Code Playgroud)

(这些贝壳的球体永远不会膨胀...,这是最明智的做法)。

bash

shopt -s dotglob
echo [.]*
Run Code Online (Sandbox Code Playgroud)

(除非您使用以文字开头的 glob ,如 in或,否则不会扩展dotglob,...不会扩展,否则类似的事情会产生意想不到的后果)。..*dir/.*chmod +rwx -- *

或者:

GLOBIGNORE=.
echo .*
Run Code Online (Sandbox Code Playgroud)

(使用bash,就像 fordotglob和出于同样的原因,一旦GLOBIGNORE非空,两者...在 globs 中都会被自动忽略不包含斜杠(并dotglob启用),这次即使使用上述文字.。请注意,GLOBIGNORE=/例如会有效果一样)。

但是请注意,.and..仍将包含在像dir/.*or 之类的全局变量中.*/file

ksh93

FIGNORE='@(.|..)'
echo .*
Run Code Online (Sandbox Code Playgroud)


小智 5

尝试一下。\xc2\xa0\n这里是手册ls -A的摘录:

\n
\n

-A,--almost-all

    不要列出隐含的...

\n

\n


frn*_*ntn 5

你想显示隐藏的文件/文件夹但是...

使用这个 bash 通配符 {.[!.]*,..?*}

样本数据

您可以尝试通过生成示例数据:

$ touch ...a  ...aa  ..a  ..aa  .a  .aa  .aaa  a
$ mkdir ...b  ...bb  ..b  ..bb  .b  .bb  .bbb  b
Run Code Online (Sandbox Code Playgroud)

证明

您可以在下面看到预期的已删除条目:

$ diff <(\ls -a) <(\ls -ad {.[!.]*,..?*})
1,3d0
< .
< ..
< a
11d7
< b
Run Code Online (Sandbox Code Playgroud)

用于删除所有隐藏元素,例如:

$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'

# <regenerate sample data here>

$ rm -rf {.[!.]*,..?*}
# No error
Run Code Online (Sandbox Code Playgroud)

  • 使用现代 bash,您可以分解出 * `{.[!.],..?,}*` (2认同)