Làm cách nào để di chuyển đệ quy tất cả các tệp (bao gồm cả ẩn) trong thư mục con vào thư mục mẹ trong * nix?


14

Đây là một câu hỏi hơi lúng túng, nhưng tôi phải thừa nhận rằng vào cuối sự nghiệp này, tôi vẫn còn thắc mắc về lệnh mv.

Tôi thường xuyên gặp vấn đề này: Tôi cần di chuyển tất cả các tệp đệ quy lên một cấp. Giả sử tôi có thư mục foo và một thanh thư mục bên trong nó. Bar có một mớ hỗn độn các tệp và thư mục, bao gồm các tệp và thư mục dấu chấm. Làm thế nào để tôi di chuyển mọi thứ trong thanh đến cấp độ foo?

Nếu foo trống, tôi chỉ cần di chuyển thanh một cấp ở trên, xóa foo và đổi tên thanh thành foo. Một phần của vấn đề là tôi không thể tìm ra ký tự đại diện của mv cho "mọi thứ bao gồm cả dấu chấm" là gì. Một phần của câu hỏi này là - có một cuộc thảo luận sâu về các ký tự đại diện mà các lệnh cp và mv sử dụng ở đâu đó (googling điều này chỉ mang lại các hướng dẫn rất cơ bản).

Câu trả lời:


19

Trong Bash (và một số người khác), bạn có thể sử dụng mở rộng cú đúp để thực hiện điều này trong một dòng:

mv bar/{,.}* .

Dấu phẩy phân tách một dấu rỗng và dấu chấm, vì vậy mvlệnh sẽ thấy tên tệp khớp với *.*


điều này cũng cố gắng di chuyển '..', thất bại với thông báo 'tài nguyên đang bận'. Tuy nhiên, hoạt động.
Xananax

3
Được đề xuất bởi người dùng ẩn danh:To eliminate the error caused by also matching "." and "..", use this command: mv bar/{,.[!.],..?}* .
HoplessN00b

2

Cách dễ nhất để làm điều này là thực hiện theo hai lệnh, bởi vì * không khớp. Dù sao đi nữa

cd /foo
mv bar/* ./
mv bar/.??* ./

Bạn không muốn sử dụng thanh /.* mà tôi đã phát hiện ra trong khi phạm lỗi này:

rm -rf ./.* 

Đây là một điều xấu. Có ai muốn đoán tại sao không? ;-)


Tôi không nghĩ Bash hay Zsh mở rộng .*ra .... Zsh không cho tôi ít nhất.
Mikael S

Mikael: Tôi có thể hứa rằng bash thực hiện (hoặc ít nhất là đã làm), vì tôi phải khôi phục các thư mục người dùng mà tôi đã xóa sạch bằng cách đó
Matt Simmons

2

Điều đầu tiên cần biết về Globing - được thực hiện bởi shell chứ không phải lệnh. Kiểm tra trang người đàn ông của bạn để biết tất cả các chi tiết.


2

Cái này thu hoạch tất cả các tệp từ các thư mục con và chuyển chúng đến thư mục hiện tại

find . -type f -exec mv -iv \{} . \;

Nếu bạn muốn ghi lại các tệp có cùng tên, hãy sử dụng

yes y | find . -type f -exec mv -iv \{} . \;

1

mv .??* *sẽ chăm sóc bất cứ điều gì ngoại trừ dấu chấm theo sau bởi một ký tự duy nhất. Nếu đó là phổ biến cho tình huống của bạn, bạn có thể thêm .[a-zA-Z0-9]*. Đó vẫn sẽ để lại các tập tin với những cái tên như .;, .^.^I(tab). Nếu bạn cần xử lý mọi thứ, bạn sẽ cần phức tạp hơn một chút.

mv .. `ls -f | egrep -v '^.$|^..$'

0

Nếu bạn có cấu trúc thư mục /foo/bar/và bạn muốn di chuyển tất cả các tệp theo barmột bước ở trên, hãy vào barthư mục và nhập như sau:

find . -depth -print0 | cpio --null -pvd ../

Nói chung, tôi nghĩ cpio(1)là tốt hơn cho các loại nhiệm vụ. Bạn có thể kiểm tra các tài liệu chi tiết bằng cách phát hành info cpiotrong vỏ của bạn.

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.