我知道使用 using.[!.]*
来引用目录中除 之外的所有点文件..
,但是如何引用除 和 之外的所有点..
文件.git
?我已经尝试了.[!.||.git]*
和.[!.][!.git]*
等的几种变体,但没有一个引用预期的文件。
答案1
您可以在 bash 中使用扩展的通配符:
shopt -s extglob
ls .!(.|git)
不过,这也匹配.
,所以你可能需要
ls .!(|.|git)
答案2
您可以使用查找:
find . -type f '!' -iname ".git" -exec cp -rv {} /dest/path \;
它将搜索当前目录中的所有文件,但不包括.git
我们使用的! -iname
(其中!
表示不等于)然后它将文件复制到目标位置
更新
find . -not -path '.' -not -path './.git' -iname '.*'
我们也可以-iregex
在 find 中使用
find . -not -iregex '.\|./.git' -iname '.*'
这两个示例都将引用当前路径中除..
和 之外的所有点文件.git
答案3
如果您想递归地查找除和 其中的任何隐藏文件之外的所有隐藏文件(包括名称以 开头的文件.
以及名称以递归方式开头的目录中的文件) ,您可以执行以下操作:.
.git
LC_ALL=C find . -path ./.git -prune -o -path '*/.*' -print
要将它们复制到其他地方,您需要停止find
在这些隐藏目录中搜索:
LC_ALL=C find . -path ./.git -prune -o -name '.?*' -prune -exec sh -c '
exec cp -Rip "$@" /path/to/destination/' {} +
(该选项将在和最终复制为-i
时提示用户)。./foo/.file
./bar/.file
/path/to/destination/.file
通过 GNU 实现cp
,sh
可以通过其选项来避免-t
:
LC_ALL=C find . -path ./.git -prune -o -name '.?*' -prune \
-exec exec cp -ait /path/to/destination/ {} +
这些仅跳过顶级.git
目录/文件。跳过任何 .git
文件,即使是子目录中的文件,也替换-path ./.git
为-name .git
.
答案4
在 zsh 中,就像在 Forsyth shell 和衍生品(pdksh 和衍生品,例如 mksh)中一样,.
并且..
永远不会包含在其 glob 扩展中,因此要列出.*
当前工作目录中的文件(除了 ).git
,还排除一列上的特殊条目.
和..
导航条目,您可以可以做:
set -o extendedglob
print -rC1 .^git(N)
.
从 5.2 版开始,除非关闭 globskipdots 选项,否则..
默认情况下也会将其排除。bash
扩展的 glob 语法是在 ksh88 之后形成的,并且 bash 没有print
on 1
C
olumn 的内置命令,并且N
ullglob 选项无法使用 glob 限定符在每个 glob 基础上打开,因此等效项必须类似于:
println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
shopt -s extglob nullglob
println .!(git)
在旧版本中,.
可以..
包含在 glob 扩展中,除非启用了 dotglob 选项并且.
未显式匹配,因此在这些旧版本中,您可以执行以下操作:
println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
shopt -s extglob nullglob dotglob
println [.]!(git)
[.]
而不是.
所以匹配不是明确的。
或者通过以下方式明确排除它们:
println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
shopt -s extglob nullglob
println .!(|.|git)
自 ksh93u+m 2020-08-09 起,ksh93 会自行跳过.
。..
从 ksh93s 开始,它也具有与 zsh 的 glob 限定符等效~(N)
的功能。N
function println { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
println ~(N).!(git)
在旧版本中,您可以执行以下操作:
function println { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
FIGNORE=.:..
println ~(N).!(git)
请注意,尽管该设置FIGNORE
意味着隐藏文件不再从 glob 中排除,因此将其设置为 与在 zsh 或 bash5.2+ 中.:..
设置该选项具有相同的效果。dotglob
bash 有一个GLOBIGNORE
与 ksh 类似的变量FIGNORE
,但是它的设计很糟糕所以我不建议使用它。
当然,您也可以通过以下方式显式排除它们:
function println { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
println ~(N).!(git)