我正在尝试将目录 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
但您可能会找到更清洁的解决方案。