Làm thế nào để di chuyển tất cả các tập tin bên trong các thư mục con hiện tại lên đây


8

Tôi cũng có 50 thư mục với một số thư mục con, với tổng số hơn 1000 tệp âm thanh. Tôi cần phải xóa tất cả các thư mục con và đặt tất cả các tệp ở mức hiện tại. Đã thử mv */* ./nhưng nó phàn nàn: danh sách đối số quá dài

Câu trả lời:


7

Tôi giả sử rằng phần mở rộng tệp âm thanh của bạn là .mp3

find <AudioFolderPath> -name '*.mp3' -exec mv -it <YourTargetFolder> {} +

Ghi chú:

  • Thay thế .mp3bằng phần mở rộng tệp âm thanh của bạn

  • Thay thế <AudioParentFolderPath>bằng thư mục cha nội dung các thư mục con của bạn.

  • Thay thế <YourTargetFolder>bằng đường dẫn thư mục mà bạn cần đặt tất cả các tệp vào.

  • Nếu các tệp kéo từ các thư mục con khác nhau có cùng tên, chỉ một tệp sẽ được di chuyển.

chỉnh sửa: Như Costas đã nói: "Công -itắc thực hiện mvtương tác, nó sẽ nhắc trước khi ghi đè lên các tệp hiện có"


'-t' có cho phép bạn chỉ định đích trước không? (vì tôi không có tùy chọn này trên "mv" của mình ở đây, tôi chỉ có thể giả sử như vậy khi bạn đặt thư mục đích đầu tiên và sau đó danh sách các tệp sẽ di chuyển đến đó ... nhưng nếu không, điều này sẽ cố gắng phù hợp với tất cả trong tên tệp cuối cùng, đưa ra cảnh báo) tcó thể là "mục tiêu"?
Olivier Dulac

Có như bạn đã nói, -tcho phép xác định đích trước. từ mvtrang hướng dẫn: -t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY
Muhammad

1
xin lưu ý rằng đây là tùy chọn của GNU mv và không có sẵn trên mọi đơn vị (ít nhất là trong một số môi trường sản xuất). Tôi cung cấp một giải pháp di động hơn, nhưng giải pháp của bạn hoạt động tốt cho Linux
Olivier Dulac

vâng @OlivierDulac, bạn đã đúng, cảm ơn bạn đã lưu ý.
Muhammad

4
find . -type f -mindepth 2 -exec mv -t ./ {} +

Lưu ý rằng lệnh đó sẽ ghi đè lên bất kỳ tệp nào có cùng tên. Bạn có thể sử dụng điều này để được nhắc trước khi ghi đè:

find . -type f -mindepth 2 -exec mv -it ./ {} +

Giải trình

  • -type f : chỉ tìm tập tin thông thường.
  • -mindepth 2 : chỉ tìm các tệp trong thư mục con.
  • -exec mv -it ./ {}: -execcó nghĩa là "chạy lệnh này trên mỗi tệp được tìm thấy". Các {}sẽ được thay thế bằng tên tập tin. Công -itắc thực hiện mvtương tác, nó sẽ nhắc trước khi ghi đè các tệp hiện có và -tđặt thư mục đích thành ./.
  • +: đặt các tệp lại với nhau (trong một dòng đối số) sao cho shell có thể hoạt động bằng lệnh để gọi lệnh thời gian tối thiểu của lệnh (không phải từng cái một mà là một đến nhiều).

Về việc xóa thư mục trống hơn nữa, bạn có thể sử dụng cùng một recepie:

find . -type d -empty -delete

1
-type fchỉ chọn các tệp đơn giản, không bao gồm các liên kết tượng trưng, ​​các ống được đặt tên và các loại tương tự. Để di chuyển tất cả các tập tin khác ngoài thư mục bạn có thể làm ! -type d.
jimmij 2/2/2015

@jimmij Tôi cho rằng không ai lưu trữ các tệp âm thanh như tên ống hoặc cái gì khác. Nếu bạn lo lắng về các liên kết tượng trưng, ​​bạn có thể sử dụng -Ltham số
Costas

1
-ilà tiêu chuẩn, -tchỉ dành cho GNU (không liên quan gì đến Linux, đây chỉ là một hạt nhân được tìm thấy trong một số hệ thống GNU và không phải GNU)
Stéphane Chazelas

Tôi đồng tình với @ StéphaneChazelas: -tkhông tồn tại trên một số hệ thống (như AIX không cổ xưa)
Olivier Dulac

@OlivierDulac Hầu như không thể tìm thấy quyết định để làm hài lòng tất cả mọi người vì vậy các biến thể khác nhau đều được chào đón. Không ai cấm bạn thay đổi chuỗi thànhfind . -type f -mindepth 2 -exec mv {} ./ \;
Costas

2

Có, đó là giới hạn về kích thước tích lũy của các đối số và môi trường được truyền cho lệnh execve()gọi hệ thống khi thực hiện lệnh bên ngoài.

Với zsh, bạn có thể sử dụng nội dung của nó mvthay thế:

zmodload -F zsh/files +b:zf_mv
zf_mv ./*/* .

Hoặc sử dụng zargsđể chia danh sách thành các phần có thể quản lý:

autoload zargs
zargs -Ifiles ./*/* -- mv files .

Với ksh93:

command -x mv ./*/* .

Với GNU xargsvà với GNU mvcó shell printfđược dựng sẵn (hầu hết, mkshlà ngoại lệ đáng chú ý):

printf '%s\0' ./*/* | xargs -r0 mv -t .

Xin lưu ý rằng OP chỉ muốn di chuyển các tệp chứ không phải các thư mục, vì vậy bạn cần quan tâm đến điều đó. Trong zshtrường hợp bạn có thể đặt một số vòng loại toàn cầu , ví dụ (.)hoặc (^/)sau cùng *.
jimmij 2/2/2015

0

Một giải pháp khá di động có thể là:

tìm tất cả các tệp trong mỗi thư mục con và di chuyển chúng trong thư mục hiện tại

find ./*/ -type f -print | xargs mv -i "{}" ./

Bạn có thể thêm một | egrep "\.au$|\.mp3$|\.ac3$"ở giữa để đảm bảo các tệp bạn tìm thấy là các tệp có phần mở rộng âm thanh (thêm càng nhiều phần mở rộng cần thiết để bao gồm tất cả các loại, tôi chỉ cung cấp 3 tệp phổ biến)


Trong trường hợp của bạn không cần phải gọi findgì cả. Vừa đủ echohoặcprintf
Costas

@Costas: OP đề cập có rất nhiều tệp mà "*" không thể mở rộng ... Ở đây tôi chỉ mở rộng 50 tên thư mục và phần còn lại được xử lý bởi xargs
Olivier Dulac

Nhưng findkhông giải quyết vấn đề mà xargslàm.
Costas
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.