Sao chép nội dung thư mục bằng lệnh 'cp'


33

Làm thế nào để bạn sao chép tất cả nội dung của một thư mục vào một thư mục khác?

Ví dụ:

$ cd /home/newuser
$ cp -a /backup/olduser/* .

Vấn đề ở trên là mẫu hả hê '*' khớp với các thư mục ẩn '.' và '..' và bạn kết thúc với một thư mục 'olduser' bên trong 'newuser', cũng như nội dung.

Bạn cũng có thể làm một cái gì đó như thế này:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

Nhưng nếu người dùng mới đã chứa một số tệp và thư mục mặc định thì sao?

Cách đơn giản nhất, chính xác nhất, dễ nhớ nhất và không lộn xộn để di chuyển nội dung của thư mục này sang thư mục khác chỉ bằng lệnh 'cp' cơ bản và trình bao?

Câu trả lời:


31

Thử:

cp -ra /backup/olduser/. /home/newuser

Điều này thật tuyệt, nhưng tôi không thể tìm ra chính xác nó hoạt động như thế nào. Tôi nghĩ có lẽ bởi vì tôi không hiểu cách thức ...công việc. Quan tâm để giải thích?
bradley.ayers

Điều này làm việc cho tôi nhưng cp -r ./a bkhông. Bất cứ ý tưởng tại sao?
Brig

3
làm việc cho tôi quá, nhưng rtùy chọn là không cần thiết. Các atùy chọn ngụ ý r.
MountainX

1
tham số -r có vẻ hơi dư thừa vào thời điểm này!
Bậc thầy lễ kỷ niệm

Các -athông số làm gì để giúp đỡ trong tình huống này. Lệnh cp -r ./a/. bsẽ sao chép nội dung và chỉ nội dung của thư mục avào thư mục b. Các -abảo tồn cờ liên kết, timestamps vv, mà không liên quan đến câu hỏi.
Steen Schütt

23

Hai thư mục a và b.

Cả hai đều có tập tin trong.

Bạn đang ở trong một thư mục chứa a và b.

cp -r ./a b

-r = đệ quy.


Bạn không muốn -a để có được tất cả các tập tin?
bw

7
Đối số -a không liên quan gì đến tất cả các tệp, đó là lưu trữ ngắn, nó sẽ bảo vệ quyền sở hữu tệp, quyền, thời gian truy cập, v.v ... Đối số -a (trong khi rất hữu ích) không phải là một tùy chọn tiêu chuẩn và một số triển khai cp 't cung cấp nó.
theotherreceive

1
@mch: tự động được bao gồm, bởi vì bạn đã yêu cpcầu sao chép một thư mục aa/.somedotfileđược chứa bởi a. nếu btồn tại, lệnh này sẽ tạo một bản sao chính xác atại b/a.
quack quixote

2
Cách dễ dàng:cp -R /some/dir/* /another/dir
n0pe

1
Điều này sao chép a / foo thành b / a / foo thay vì b / foo
Sparr

19

Hãy nhớ rằng, theo mặc định, cpsao chép thư mục đầu tiên vào thư mục thứ hai nếu thư mục thứ hai tồn tại.

Ví dụ cp -r a bsẽ sao chép thư mục a vào b. Nếu bkhông tồn tại, nó sẽ được tạo với nội dung của a.

Nếu bạn muốn sao chép nội dung của athành b(ví dụ như khi sao chép một hệ thống tập tin toàn bộ vào một điểm gắn kết) sử dụng:

cp -r a/. b

như trong câu trả lời trước.

Cũng xin lưu ý rằng -a, được sử dụng trong một số câu trả lời khác, giống như -dr --preserve=allvà sẽ duy trì dấu thời gian, bối cảnh và các thuộc tính mở rộng.


Làm thế nào để /.làm việc?
bradley.ayers

a/.đại diện cho nội dung của thư mục 'a' trái ngược với chính thư mục, trong hầu hết các trường hợp, nó đồng nghĩa nhưng khi sử dụng cp -r, nó sẽ tránh hành vi mặc định của cp (sao chép INTO b).
Nicolas Bonefon

mẹo tuyệt vời, đây chính xác là những gì tôi đang tìm kiếm nhưng không tìm thấy ở nơi nào khác - tất cả những gì 'foo / *' hoặc '-r foo /' không thành công trong các trường hợp góc.
Tener

@TimoHuovinen '.' hoàn toàn không phải là ký tự đại diện. Đó đúng là thư mục "cha mẹ" và '..' là ông bà. Điều này có nghĩa là '/foo/./././././.' là cùng thư mục với '/ foo' và '/ foo / bar / ..' là cùng thư mục với '/ foo'. Hãy nghĩ về chúng như các liên kết cứng được tích hợp vào hệ thống tập tin.
quuxman

@quuxman cảm ơn bạn, lúc đó tôi không biết về nó. Tôi sẽ xóa bình luận cũ của tôi để tránh gây nhầm lẫn cho mọi người.
Timo Huovinen

6

Trừ khi bạn đã cấu hình lại nghiêm túc vỏ của mình, mẫu hình cầu '' 'không khớp'. ' hoặc '..', như bạn có thể xác minh bằng cách chỉ sử dụng echo *. Thay vào đó, những gì nó làm là bỏ qua các tệp có tên bắt đầu bằng '.', Vì vậy cách tiếp cận của bạn sẽ bỏ lỡ tất cả các tệp bị ẩn. Bạn có thể điều chỉnh một số hành vi này bằng các tùy chọn shell, ví dụ tùy chọn dotglob trong bash, nhưng sau đó sẽ không phải là tùy chọn di động và mạnh mẽ mà bạn đang tìm kiếm.

Nếu bạn cần thực hiện việc này nhiều hơn một hoặc hai lần, tôi khuyên bạn nên xem xét rsync hoặc unison (tùy thuộc vào nhu cầu cụ thể) với các thông số kỹ thuật mục tiêu và nguồn được chế tạo cẩn thận.

Một cách khác là đặt thư mục nguồn trong tarball và gỡ nó ra khỏi thư mục đích hiện có.


1
tôi sử dụng cái này: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - )... tar cf - .thư mục nguồn của tar, bao gồm các dotfiles và gửi nó đến STDOUT, được chuyển đến STDIN của tar xf -.
quack quixote

Tôi nghĩ rằng toàn bộ quan điểm của OP là làm thế nào để tham chiếu các tệp bắt đầu bằng '.' nhưng không phải là đặc biệt '.' và các thư mục '..'. Có một giải pháp thanh lịch hơn nhiều ở trên thay vì sử dụng rsync hoặc một số chương trình phức tạp khác.
quuxman

2

Điều này sẽ sao chép cả các tệp bình thường và ẩn, trong khi loại trừ thư mục mẹ ( ..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

Nếu bạn không loại trừ thư mục mẹ, bạn cũng sẽ có tất cả nội dung ..trong thư mục đích của mình.


1
Nhưng điều này vẫn loại trừ các tên bắt đầu bằng .. (ví dụ: ...hoặc ..super-hidden).
Scott

0

Để sao chép các tệp bắt đầu bằng dấu chấm, chỉ cần thực hiện cp. * Target /

Vì vậy, dễ nhất là chỉ cần thực hiện lệnh cp hai lần.

Như Peter Eisentraut sais quy tắc hình cầu bình thường không bao gồm .. và. (hm, làm thế nào để kết thúc câu này ?;)

Chỉ cần sử dụng -r để làm cho nó đệ quy và -i để tạo cp hỏi bạn có thực sự muốn ghi đè lên một tệp không.

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/

Thường *không phù hợp .hoặc .., nhưng nó không nếu bạn sử dụng .*. Hãy thử echo .*. Bạn có thể loại trừ ...với mẫu sau : .[^.]*.
mch

@mch: Nhưng .[^.]*vẫn loại trừ các tên bắt đầu bằng .. (ví dụ: ...hoặc ..super-hidden).
Scott

0

Điều này hoạt động để sao chép tất cả các tệp và thư mục ngoại trừ các thư mục ẩn được đệ quy từ thư mục hiện tại đến bất cứ nơi nào:

cp -rf * ^.* 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.