仅将常规文件从一个目录复制到另一个目录


12

我想将目录1的内容复制到目录2。但是,我只想从目录1复制文件(而不复制目录)。我该怎么做?

cp dir1/* dir2/*

那么我仍然有目录问题。

另外,我的所有文件都没有扩展名,因此不会成功的


1
不知道扩展与它有什么关系。
ctrl-alt-delor

1
cp dir1/* dir2cp -t dir2 dir1/*
ctrl-alt-delor

@richard在DOS世界中有一种相当普遍的习惯,就是不使用目录扩展名,这种习惯在某种程度上仍然存在,导致某些人认为如果有一个点,那么它就不是目录,反之亦然。
吉尔(Gilles)'所以

好的,但仍然没有关系。
ctrl-alt-delor

Answers:


18
cp dir1/* dir2

cp除非明确要求这样做,否则不会复制目录(--recursive例如,请参见man cp)。

注意1: cp最有可能以非零状态退出,但是无论如何文件都将被复制。基于退出代码链接命令时,这可能是一个问题:&&||if cp -r dir1/* dir2; then ...等(感谢contrebis他们在这个问题上的评论

注2cp期望最后一个参数是单个文件名或目录。*在目标目录的名称后面确实不应有通配符。dir2\*会像一样被shell扩展dir1\*。意外的事情将会发生:

  • 如果dir2为空,并且取决于您的外壳和设置:
    • 您可能只会收到一条错误消息,这是最好的情况。
    • dir2/*将从字面上获取(查找名为的文件/目录*),这也可能导致错误,除非*实际存在。
    • dir2/*它将完全从命令中删除,离开cp dir1/*。根据的扩展dir1/*,甚至可能破坏数据:
      • 如果dir1/*仅匹配一个文件或目录,则将出现错误cp
      • 如果dir1/*恰好匹配两个文件,则一个文件将被另一个文件(Bad)覆盖。
      • 如果dir/*匹配多个文件,而最后一个匹配为a,您将收到一条错误消息。
      • 如果的最后一个匹配项dir/*是目录,则所有其他匹配项都将移入该目录。
  • 如果dir2不为空,则再次取决于:
    • 如果的最后一个匹配项dir2/*是目录,dir1/*则的其他匹配项dir2/*将被移入。
    • 如果的最后一个匹配dir2/*是一个文件,除非 dir1/*仅匹配一个文件,否则您可能会收到一条错误消息。

$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).为我退出,状态为1。
contrebis '16

1
是的,它也确实以状态1退出。但是即使如此,还是cpdir1/*在我检查过的每个系统上都复制匹配的文件:Arch Linux,Ubuntu 14.04,OpenBSD 3.9和5.5,SuSE Linux 8.1,FreeBSD 6.2,Solaris 8、9和10(cp实际上以代码2退出)。因此,这种行为既不是新的(SuSE 8.1是2002年发布的),也不限于Linux。cp使用非零退出代码退出,因为它无法完成被告知要执行的所有操作。那并不意味着它什么也不做
阿达芬

3
当然,我想值得注意,因为如果您将命令链接在一起&&会导致问题。尽管我现在不记得上下文了,但我仍在尝试类似的操作。
contrebis '16

这不会复制隐藏文件。
felwithe 18-4-25

@felwithe是否*包含隐藏文件或如何包含隐藏文件取决于外壳。如果*中不包含隐藏文件,则可以将它们匹配.*。请注意,这将包括...bashdash但不是zsh。在此答案的上下文中,您可以避免cp dir1/* dir1/.* dir2因为...是目录,并且不会被复制。zsh也可以使用包含隐藏文件*(D)
Adaephon '18

7

是扩展通配符的外壳,而不是命令。因此,cp dir1/* dir2/*首先扩展两个通配符,然后调用cp结果。这显然不是您所期望的:取决于已存在的文件数dir2dir2/*可能会扩展为一个或多个参数。该命令cp不知道它的哪些参数来自扩展第一个模式,哪些参数来自扩展第二个模式。它期望其最后一个参数是目标目录的名称。因此,要将目录中的所有文件复制dir1到目录中dir2,最后一个参数必须是目录dir2

cp dir1/* dir2

由于*匹配所有文件,因此cp尝试复制所有文件。这包括目录:目录也是文件。它跳过目录,但是报告错误。它复制特殊文件的内容,例如命名管道(最好将其写入其中,否则cp将阻止)等。

要仅复制常规文件,您需要限制匹配。在zsh中,可以为此使用glob限定符 .

cp dir1/*(.) dir2

其他外壳没有这个。您可以使用该find命令过滤文件类型。假设您正在运行非嵌入式Linux或Cygwin:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

在Linux,FreeBSD和OSX上:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2

有理由指定-maxdepth 1。另外,是否有一种方法可以递归复制并在目标目录中保留原始目录层次结构?
阿卜杜勒

@Abdull如果不使用-maxdepth 1,该find命令将递归到子目录中,这在这里是不需要的。如果要复制包括子目录在内的整个目录树,则是一个完全不同的问题,答案要简单得多:cp -a dir1 dir2
吉尔(Gilles)“所以,别再邪恶了”

0

下面是将文件从源复制到目标目录的命令。

  1. 转到源文件夹,然后编写以下命令:

    $ cp fileName destination directory path

例:

cp publichOT.sh  /data/home/useradmin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.