如何复制以点开头的文件?

如何复制以点开头的文件?

我正在尝试将目录 A 下的所有文件复制到目录 B。目录 A 下的所有文件都以点开头,例如:

A/.a
A/.b
A/.c

我发现如果我使用:cp A/* B,总是会出现错误:

cp: cannot stat 'A/*': no such file or directory

似乎没有选项cp可以ls处理以点开头的条目,有人知道如何修复它吗?

答案1

原因是bash,中*不包含以点 ( .) 开头的文件。

你可以运行

cp A/.* B

它会警告您它没有复制...或任何子目录,但这没问题。

或者,如果你想将点文件和普通文件一起复制,请运行

cp A/.* A/* B

你也可以运行

shopt -s dotglob
cp A/* B

这将在 中起作用bash,但不能sh

如果你不介意子目录也被复制,那么这是最简单的:

cp -R A/ B

提示:如果通配符没有达到你的预期,请尝试使用 echo 运行它,例如

$ echo A/*
A/file1 A/file2

$ echo A/.*
A/. A/.. A/.hidden1 A/.hidden2

$ echo A/.* A/*
A/. A/.. A/.hidden1 A/.hidden2 A/file1 A/file2

$ shopt -s dotglob
$ echo A/*
A/file1 A/file2 A/.hidden1 A/.hidden2

答案2

如果是 bash,你可以dotglob在复制之前进行设置

shopt -s dotglob
cp A/* /destination

或者一种编程语言

$ ruby -rfileutils -e  'Dir[".*"].each {|x| FileUtils.copy(x,"/destination") if File.file?x}'

如果你不想设置 dotglob,只需

cp A/.* /destination 2>/dev/null

答案3

您正在寻找的内容更接近于以下内容:

cp A/.??* B/

这将匹配所有点文件,但不会匹配“。”或“..”。只要您不是以递归方式工作,上述大多数解决方案都可以。但是,只要您想执行类似以下操作:

cp -R A/.??* B/

如果不省略“..”,您将从父目录向下复制所有内容,包括非点文件。

答案4

cp不是过错,它是 bash:bash*在所有非隐藏(即:不以 开头.)的文件中扩展。

Bash 将扩展.*(因此A/.*在您的情况下为)所有以 开头的文件.,但不幸的是,它还包括...(当前目录和父目录),您可能想要跳过它们。 (请注意,其他 shell,如 zsh,不会包括它们,IIRC 在设置一些选项后也不会包括 bash)。

一个简单的解决方案可能是从 匹配的文件中删除.和,以一种(非常)黑客的方式,如下所示:...*

cp $( for F in A/.*; do echo $F | grep -v "^\.*$"; done ) B

或者这个(可能更干净:它用来find查找要复制的文件):

cp $( find A -maxdepth 1 -mindepth 1 -name ".*" ) B

但您可能会找到更清洁的解决方案。

相关内容