将文件从一个目录复制到已存在的目录中。

311
在bash中我需要做以下操作:
  1. 获取目录中的所有文件

  2. 将它们复制到一个已存在的目录中

如何实现呢?我尝试了cp -r t1 t2 (t1和t2都是已存在的目录,t1中有文件),但它创建了名为t1的目录在t2里,我不想要那样,我需要t1中的文件直接放到t2中。我该怎么做?

13
为什么这个问题被关闭了?如果一个Bash命令是内置的或外部的(例如,大多数系统上都存在printf),那么这是任意的,因此cp问题可以很好地被视为bash问题,它是一种编程语言。我从来没有见过一个关于文件拷贝的Python问题被关闭。 - Ciro Santilli OurBigBook.com
看一下这个 https://dev59.com/-mAg5IYBdhLWcg3wWpz- - theGiallo
我在寻找Bash shell复制命令的语法提醒,很高兴地报告这些命令似乎也适用于Windows上基础的NTFS文件系统。 - David A. Gray
10个回答

488

你想要的是:

cp -R t1/. t2/

末尾的点表示复制当前目录的内容,而不是目录本身。此方法还包括隐藏文件和文件夹。


4
我很喜欢这个句法,但出于某种原因它在使用 mv 时不起作用。有人知道为什么吗? - Martin von Wittich
2
太棒了。这个在哪里有记录?它是POSIX标准还是扩展功能? - Ciro Santilli OurBigBook.com
12
如果你复制一个文件夹,cp命令将会创建一个新的文件夹并将其中所有文件都复制进去。如果你使用一个名为“.”的虚拟文件夹,它与所在的文件夹相同,那么复制操作会按照这种方式执行。假设t1中包含一个名为“file”的文件。cp命令将执行等同于“cp t1/./file t2/./” 的操作。它在复制文件夹“。”,但是将文件复制到t2下的“.”文件夹中时,会去掉“./”,因为“t2/./”和“t2/”是一样的。就技术层面而言,这是POSIX内置行为......但可能不是你原先期望的那种方式! - striking
当我使用源路径尾随一个点(t1 /。)进行测试时,它将整个t1文件夹及其内容复制到t2文件夹中。因此,我在t2文件夹中得到了一个t1文件夹。但是,一旦我使用*而不是点,它就可以正常工作,并将t1的内容仅复制到t2中。因此,我认为这个问题的最佳答案是以下脚本-> cp -R t1 / * t2 /。 - CodeMan

47
cp dir1/* dir2

或者如果你在dir1内有目录需要一并复制

cp -r dir1/* dir2

3
根据您的Shell配置不同,如果您想同时匹配隐藏文件,则可能需要使用"dir1/* dir1/."而不是"dir1/"。 - ssokolow
2
复制 dir1/.* 不是一个好主意,因为它会复制 dir1/..(即您实际尝试复制的目录的父目录)。它还会复制 dir1/.,这很好,除非它已经(大部分)被复制了,所以您正在做重复的工作。 - Gordon Davisson
1
你可以通过进入想要复制的目录并将其称为“.”来解决dir1/.*/隐藏文件问题。因此,如果您想将包括隐藏文件在内的所有文件从一个目录复制到现有目录中,您可以执行以下操作:cd [源目录]cp . [目标目录路径,不带尾部斜杠] - RobW

36

如果你想把某个东西从一个目录复制到当前目录,可以执行以下操作:

cp dir1/* .

假设你不想复制隐藏文件。


1
同样也无法处理大量文件(因为“*”无法扩展到无限多个文件。。。) - moritzschaefer

8
假设t1是有文件的文件夹,而t2是空文件夹。您需要的是像这样的东西:
sudo cp -R t1/* t2/

记住,在第一个示例中,t1和t2必须是完整路径或相对路径(基于您所在的位置)。如果您愿意,可以导航到空文件夹(t2)并执行以下操作:
sudo cp -R t1/* ./

或者,您可以导航到包含文件(t1)的文件夹并执行以下操作:

sudo cp -R ./* t2/

注意:星号(或通配符)代表所有文件和文件夹。-R标志表示递归(包括所有内部内容)。

6
cp -R t1/ t2

源目录末尾的斜杠会稍微改变语义,这样它就会复制内容而不是目录本身。它还避免了Bertrand答案中出现的通配符和隐藏文件的问题(复制`t1/*`会忽略隐藏文件,复制`t1/* t1/.*`会复制t1/.和t1/..,这是不想要的)。

你的解决方案不起作用,至少在我的安装(ubuntu 12.10)上不起作用。$ mkdir t1 $ mkdir t2 $ touch t1/one $ touch t1/two $ touch t1/.three $ cp -R t1/ t2 $ ls t2/ t1 (抱歉评论中没有代码格式,可在http://pastebin.com/yszSxV6G查看可读版本) - zpon
感谢您的详细解释! - Volodymyr Kulyk

6

对于某个目录内部,这将非常有用,因为它会将“folder1”中的所有内容复制到新目录“folder2”中。

$(pwd)将获取当前目录的路径。

请注意,在folder1后面加上点(.),以获取folder1中的所有内容。

cp -r $(pwd)/folder1/. $(pwd)/folder2

5

2021年11月更新:

在使用标志“-R”的情况下,此代码将完美地复制"folder1"中的所有内容到现有的"folder2"中:

cp -R folder1/. folder2

标志"-R"会同时复制符号链接,而标志"-r"会跳过符号链接,因此标志"-R"标志"-r"更好。

  • 最新的GNU Grep 3.7版本
-R, --dereference-recursive

For each directory operand, read and process all files in that directory, 
recursively, following all symbolic links.

-r, --recursive

For each directory operand, read and process all files in that directory, 
recursively. Follow symbolic links on the command line, but skip symlinks 
that are encountered recursively. Note that if no file operand is given, 
grep searches the working directory. This is the same as the 
‘--directories=recurse’ option.

2

根据一些细节,您可能需要像这样做:

r=$(pwd)
case "$TARG" in
    /*) p=$r;;
    *) p="";;
    esac
cd "$SRC" && cp -r . "$p/$TARG"
cd "$r"

这基本上是切换到SRC目录并将其复制到目标位置,然后返回到您开始的位置。

额外的麻烦是为了处理相对或绝对目标。

(这不依赖于cp命令本身的微妙语义...关于它如何处理带有或不带有尾随/的源规范...因为我不确定这些是否稳定、可移植和可靠,除了GNU cp以外,我也不知道它们将来是否会继续存在。)


0
在我的情况下,在Ubuntu 20.04.6上,Bash不接受我的双引号命令。例如:
cp "$HOME/.local/lib/*" ./lib/

返回 =>

$>cp: 无法查找 '/home/user1/.local/lib/*':没有那个文件或目录

该目录在我的系统上存在,所以它可能会将星号字面解释。通过删除引号,它可以工作。这里是关于bash引用变量解释的参考页面。


你也可以将其修改为 cp "$HOME/.local/lib/"* ./lib/ - NickS

0

正确的选项应该是-T。与-r一起使用以进行递归复制。

$ cp -r -T t1 t2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接