Đoạn trích Bash để di chuyển tất cả các tệp trong một thư mục vào thư mục đó


14

Tôi có một thư mục chứa rất nhiều tập tin và thư mục trong đó. Để dọn dẹp nó, tôi sẽ đặt tất cả các tệp đó vào một thư mục, vì vậy tôi sẽ làm một cái gì đó như thế này:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Tuy nhiên, điều đó rõ ràng sẽ không hoạt động vì sau đó nó sẽ cố gắng chuyển new_directoryvào new_directory. Có một số cách đơn giản để làm những gì tôi muốn trong một dòng mà không cần tôi phải sao chép và dán tất cả các tệp và thư mục trong thư mục đó?


3
nó hoạt động, nó chỉ in một thông báo lỗi rằng nó không thể di chuyển new_directory vào chính nó.
cas

Câu trả lời:


18

Của bạn

mv * ./new_directory
lệnh sẽ thực sự hoạt động; nó sẽ chỉ in một cảnh báo rằng nó không thể di chuyển thư mục đó vào chính nó.


Vấn đề 'duy nhất' với điều này là nếu việc mở rộng toàn bộ lệnh trở nên quá dài (tức là quá nhiều tệp, tên quá dài) thì điều này sẽ không còn hoạt động.
Niels Basjes

Như một lưu ý phụ, nếu bạn định làm điều này với một cờ git mvbạn phải sử dụng -kcờ, vì git sẽ bị lỗi theo mặc định, không chỉ đưa ra cảnh báo. Vì vậy, bạn sẽ cần phải làm git mv -k * ./new_dir.
Yuval A

11

Một oneliner nhanh và bẩn.

mv `ls -A | grep -v new_directory` ./new_directory

1
Sẽ không hoạt động: một ls đơn giản sẽ không hiển thị dotfiles.
wzzrd

Điểm rất tốt. Đã sửa lỗi đó bằng một -a.

2
Vì vậy, thay vì cố gắng mv new_directory cho chính nó (Câu hỏi ban đầu), bạn hiện đang cố gắng di chuyển. và .. vào new_directory.
Niels Basjes

2
Cảm ơn các Niels phản hồi. Đã sửa nó với phần trên mà loại bỏ. và .. từ danh sách thư mục.

8

Nếu bạn chỉ tìm kiếm các tệp (tức là không phải thư mục), thì

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

là giải pháp di động nhất. Đối với tốc độ, bạn nên di chuyển find và xargs, với -print0 và -0, nhưng chỉ khi bạn có GNU find và xargs.


3
Sử dụng một tìm kiếm GNU gần đây, bạn cũng có thể sử dụng \ + thay vì \; để giảm số lượng mv của chúng tôi đang thực hiện.
wzzrd

Nếu bạn đã tìm thấy GNU, bạn cũng sẽ sử dụng xargs, điều này sẽ làm tương tự và cho phép bạn chạy nhiều mv cùng một lúc với cờ -p.
Cian

sử dụng tuyệt vời find- mặc dù tôi chắc chắn đã sử dụng các hệ thống không có, nhưng thật đáng buồn :(
warren

Có thật không? find là (afaik) được chỉ định trong SUS, vì vậy mọi thứ nên có nó. Vấn đề duy nhất là liệu GNU tìm thấy (có nhiều tùy chọn hay ho) hay tìm thường xuyên.
Cian


6

Những lần tôi gặp vấn đề này, tôi đã thực hiện một trong những điều sau đây:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

hoặc là

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

Hình thức thứ hai tận dụng các tên tệp bỏ qua ký tự đại diện bắt đầu bằng '.'


Tôi quên các tập tin chấm bỏ qua thẻ hoang dã; cảm ơn đã nhắc nhở! :)
aemrid

2

Thế còn:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, không di chuyển nội dung vào một thư mục mới, nhưng đặt thư mục này vào một thư mục mới.


1

Theo cách tương tự với câu trả lời của @ Rembrane (mặc dù không phải là một lớp lót):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Điều này nên được di động 100% - ngay cả khi findđáng buồn vắng mặt trong hệ thống của bạn.


tìm được yêu cầu trong thông số unix duy nhất. Như vậy, không bao giờ nên vắng mặt (không phải là bạn không thể tạo ra thứ gì đó ngoài nó. Nhưng tôi tưởng tượng nó sẽ đòi hỏi một nỗ lực khủng khiếp và sẽ không có hệ thống nhà cung cấp nào thiếu nó)
Cian

có lẽ đó là một số tìm kiếm sysadmin yo hoang tưởng hoặc tương đương của nó? không chắc chắn, nhưng tôi biết tôi đã chạy vào boxen mà không có nó :(
warren

1

Gợi ý của tôi: Như đã nói của người khác

mv * ./new_directory

sẽ làm việc tìm IFF tổng mở rộng là đủ ngắn.

Thông thái khác, bạn có thể thử cái này chia tỷ lệ với số lượng tệp lớn hơn nhiều:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Giải trình

  1. Liệt kê tất cả các tập tin.
  2. Nhóm tất cả các tên tệp thành các khối tối đa 100000 ký tự.
  3. Xây dựng một lệnh mv duy nhất cho mỗi đoạn.

nghỉ nếu bạn có bất kỳ khoảng trắng nào trong tên tệp của mình
Cian

Bạn đúng. Vì vậy, tôi đoán điều này nên được tăng cường với các cờ -print0 và -0 để sửa chữa.
Niels Basjes

Tôi đã thử với -print0-0và nó vẫn phá vỡ.
Cristian Ciupitu

tìm: cảnh báo: bạn đã chỉ định tùy chọn -maxdepth sau một loại đối số không phải tùy chọn -type, nhưng các tùy chọn không theo vị trí (-maxdepth ảnh hưởng đến các thử nghiệm được chỉ định trước nó cũng như các tùy chọn được chỉ định sau nó). Vui lòng chỉ định các tùy chọn trước các đối số khác.
Cristian Ciupitu

1

Sử dụng:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Từ xargstrang người đàn ông:

-P max-procs

  Run up to max-procs processes at a time;

-1

Để tránh thông báo lỗi và giữ cho nó đơn giản:

mv *.* ./new_Folder

sẽ làm điều tương tự nhưng tránh thông báo lỗi (trừ khi bạn có dấu chấm trong tên thư mục của bạn tôi đoá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.