复制除“.git”和“..”之外的所有点文件

复制除“.git”和“..”之外的所有点文件

我知道使用 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 没有printon 1 Column 的内置命令,并且Nullglob 选项无法使用 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)

相关内容