为什么根目录下的dot文件无法移动

为什么根目录下的dot文件无法移动

目录中有一些文件、文件夹和点文件,如下所示

|-folder1
|----folder2
|----file.json
|----file2.php
|----.env
|----.dockerfile
|----.someconfig
|----.dockerignore

我运行命令mv $(ls | egrep -v '(.dockerfile|.env)') ../new_directory将目录中的所有文件移动folder1new_directory排除.dockerfile.env,但实际上所有点文件都无法移动,为什么?

答案1

如果你跑

ls | egrep -v '(.dockerfile|.env)'

就其本身而言,您将了解这里发生的情况:输出将是

file2.php
file.json
folder2

发生这种情况是因为ls默认情况下不列出点文件。要包含点文件,但不包含...,请使用ls -A

$ ls -A | egrep -v '(.dockerfile|.env)'
.dockerignore
file2.php
file.json
folder2
.someconfig

你不需要ls在这里使用(并且你不应该),你可以使用 Bash 的扩展模式匹配

shopt -s extglob dotglob
mv !(.dockerfile|.env|.|..) ../new_directory

这将匹配所有文件不是命名为.dockerfile.env...。使用这种方法,您不会遇到包含空格、换行符等的文件名的任何问题。

shopt -s extglob启用扩展模式匹配,并shopt -s dotglob允许 glob 匹配点文件。

答案2

你不应该用ls这个。解析 的输出ls往好了说是不可靠的,往坏了说是危险的。看为什么不是解析ls(以及该怎么做)?

尝试find一下。例如使用 GNU find(和 GNU cp):

find ./ -maxdepth 1 -regextype awk \
  ! -regex './(|\.env|\.dockerfile)' \
  -exec echo cp -t ../new_directory/ {} +

我使用它是-regextype awk因为我非常习惯 awk 中的正则表达式方言,并且我不想浪费时间弄清楚find-default. -regextype egrep也会同样有效。您可以通过运行获取可用方言列表find -regextype help(不幸的是,PCRE 不是其中之一)。

排除、和。-regex ...​请注意,锚点和锚点都不是必需的,它们是隐式的's谓词,因此您只能得到精确匹配。如果您想要部分匹配,则必须添加到正则表达式的开头和/或结尾。这就是为什么我必须将 包含在正则表达式中。././env./dockerfile^$find-regex.*./

如果我要从父目录运行它,则必须将其写为:

find folder1/ -maxdepth 1 -regextype awk \
  ! -regex 'folder1/(|\.env|\.dockerfile)' \
  -exec echo cp -t ../newfolder {} +

或者使用与路径匹配的其他模式,例如'.*/(|\.env|\.dockerfile)'.

echo使得这是一次演练,向您展示将复制哪些内容,而无需实际复制它们。当您确认该命令将执行您想要的操作后,将其删除。

GNUcp-t选项允许您在要复制的文件列表之前指定目标目录。

相关内容