Chỉ sao chép các tệp thông thường từ thư mục này sang thư mục khác


12

Tôi muốn sao chép nội dung của thư mục 1 sang thư mục 2. Tuy nhiên, tôi chỉ muốn sao chép các tệp (chứ không phải thư mục) từ thư mục của mình 1. Làm thế nào tôi có thể làm điều đó?

cp dir1/* dir2/*

sau đó tôi vẫn có vấn đề thư mục.

Ngoài ra, tất cả các tệp của tôi không có bất kỳ phần mở rộng, vì vậy . sẽ không làm trò bịp


1
Không biết những tiện ích mở rộng nào phải làm với nó.
ctrl-alt-delor

1
cp dir1/* dir2hoặccp -t dir2 dir1/*
ctrl-alt-delor

@richard Có một thói quen khá phổ biến đến từ thế giới DOS là không sử dụng các phần mở rộng cho các thư mục, vẫn tồn tại ở một mức độ nào đó, khiến một số người cho rằng nếu có một dấu chấm thì đó không phải là một thư mục và ngược lại.
Gilles 'SO- ngừng trở nên xấu xa'

ok nhưng vẫn không liên quan.
ctrl-alt-delor

Câu trả lời:


18
cp dir1/* dir2

cpsẽ không sao chép các thư mục trừ khi được yêu cầu rõ ràng để làm như vậy ( --recursiveví dụ, xem man cp).

Lưu ý 1: cp rất có thể sẽ thoát với trạng thái khác không, nhưng dù sao các tệp sẽ được sao chép. Đây có thể là một vấn đề khi chaining lệnh dựa trên mã lối ra: &&, ||, if cp -r dir1/* dir2; then ..., vv (Nhờ contrebis cho bình luận của họ về vấn đề đó )

Lưu ý 2 : cpdự kiến ​​tham số cuối cùng là một tên tệp hoặc thư mục. Thực sự không nên có ký tự đại diện *sau tên của thư mục đích. dir2\*sẽ được mở rộng bởi vỏ giống như dir1\*. Những điều bất ngờ sẽ xảy ra:

  • Nếu dir2trống và tùy thuộc vào vỏ và cài đặt của bạn:
    • bạn có thể nhận được một thông báo lỗi, đó là trường hợp tốt nhất.
    • dir2/*sẽ được thực hiện theo nghĩa đen (tìm kiếm một tập tin / thư mục có tên *), điều này có thể cũng sẽ dẫn đến một lỗi, trừ khi *thực sự tồn tại.
    • dir2/*nó chỉ sẽ bị xoá khỏi lệnh hoàn toàn, để lại cp dir1/*. Mà, tùy thuộc vào việc mở rộng dir1/*, thậm chí có thể phá hủy dữ liệu:
      • Nếu dir1/*chỉ khớp với một tệp hoặc thư mục, bạn sẽ gặp lỗi từ cp.
      • Nếu dir1/*khớp chính xác hai tệp, một tệp sẽ bị ghi đè bởi tệp kia ( Xấu ).
      • Nếu dir/*khớp nhiều tệp và kết quả khớp cuối cùng là a, bạn sẽ nhận được thông báo lỗi.
      • Nếu trận đấu cuối cùng dir/*là một thư mục, tất cả các trận đấu khác sẽ được chuyển vào đó.
  • Nếu dir2không trống, nó lại phụ thuộc:
    • Nếu trận đấu cuối cùng dir2/*là một thư mục dir1/*và các trận đấu khác dir2/*sẽ được chuyển vào.
    • Nếu trận đấu cuối cùng dir2/*là một tệp, bạn có thể sẽ nhận được thông báo lỗi, trừ khi dir1/* chỉ khớp với một tệp.

$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).thoát với trạng thái 1 cho tôi.
contrebis

1
Vâng, nó cũng thoát với trạng thái 1 cho tôi. Nhưng ngay cả như vậy, cpcũng sao chép các tệp phù hợp dir1/*trên mọi hệ thống mà tôi đã kiểm tra: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 và 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 và 10 (trong đó cpthực sự thoát với mã 2). Vì vậy, hành vi này không mới (SuSE 8.1 là từ năm 2002) và cũng không giới hạn ở Linux. cpthoát với mã thoát khác không bởi vì nó không thể làm mọi thứ mà nó được yêu cầu. Điều đó không có nghĩa là nó không làm gì cả .
Adaephon

3
Chắc chắn, tôi nghĩ đáng chú ý bởi vì nếu bạn xâu chuỗi các lệnh cùng với &&điều này có thể gây ra vấn đề. Tôi đã cố gắng để một cái gì đó như thế này mặc dù tôi không thể nhớ bối cảnh bây giờ.
contrebis

Điều này không sao chép các tập tin ẩn.
felwithe

@felwithe Việc *bao gồm các tệp ẩn hay cách bao gồm các tệp ẩn tùy thuộc vào trình bao. Nếu *không bao gồm các tập tin ẩn, bạn có thể kết hợp chúng với .*. Lưu ý rằng điều này sẽ bao gồm ...trên bashdashkhông zsh. Trong ngữ cảnh của câu trả lời này, bạn có thể thoát khỏi cp dir1/* dir1/.* dir2...là các thư mục và sẽ không được sao chép. zshcũng có thể được thực hiện để bao gồm các tập tin ẩn với *(D).
Adaephon

6

Đó là cái vỏ mở rộng các ký tự đại diện, không phải các lệnh. Vì vậy, cp dir1/* dir2/*đầu tiên mở rộng hai ký tự đại diện, sau đó gọi cpkết quả. Đây hoàn toàn không phải là những gì bạn mong đợi: tùy thuộc vào số lượng tệp đã có dir2, dir2/*có thể mở rộng thành một hoặc nhiều đối số. Lệnh cpkhông biết đối số nào đến từ việc mở rộng mẫu đầu tiên và đối số nào đến từ việc mở rộng mẫu thứ hai. Nó hy vọng đối số cuối cùng của nó là tên của thư mục đích. Do đó, để sao chép tất cả các tệp từ thư mục dir1vào thư mục dir2, đối số cuối cùng phải là thư mục dir2:

cp dir1/* dir2

*phù hợp với tất cả các tệp, cpcố gắng sao chép tất cả các tệp. Điều này bao gồm các thư mục: thư mục là tập tin quá. Nó bỏ qua các thư mục, nhưng báo lỗi. Nó sao chép nội dung của các tệp đặc biệt như các ống có tên (một cái gì đó tốt hơn là viết cho chúng, hoặc cpsẽ chặn), v.v.

Để chỉ sao chép các tệp thông thường , bạn cần hạn chế kết hợp. Trong zsh, bạn có thể sử dụng vòng loại toàn cầu . cho điều đó:

cp dir1/*(.) dir2

Các vỏ khác không có cái này. Bạn có thể sử dụng findlệnh để lọc các loại tệp. Giả sử rằng bạn đang chạy Linux hoặc Cygwin không nhúng:

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

Trên Linux, FreeBSD và OSX:

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

Có một lý do để xác định -maxdepth 1. Ngoài ra, có cách nào để sao chép đệ quy và bảo toàn hệ thống phân cấp thư mục gốc trong thư mục đích không?
Abdull

@Abdull Nếu không -maxdepth 1, findlệnh sẽ lặp lại thành các thư mục con, điều không mong muốn ở đây. Nếu bạn muốn sao chép toàn bộ cây thư mục bao gồm các thư mục con, đó là một câu hỏi hoàn toàn khác và câu trả lời đơn giản hơn nhiều : cp -a dir1 dir2.
Gilles 'SO- ngừng trở nên xấu xa'

0

Dưới đây là lệnh để sao chép tập tin từ thư mục nguồn đến thư mục đích.

  1. Đi đến thư mục nguồn sau đó viết lệnh dưới đây:

    $ cp fileName destination directory path

Thí dụ:

cp publichOT.sh  /data/home/useradmin
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.