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
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:
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> {} +
Thay thế .mp3
bằ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 -i
tắc thực hiện mv
tương tác, nó sẽ nhắc trước khi ghi đè lên các tệp hiện có"
-t
cho phép xác định đích trước. từ mv
trang hướng dẫn: -t, --target-directory=DIRECTORY
move all SOURCE arguments into DIRECTORY
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 ./ {} +
-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 ./ {}
: -exec
có 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 -i
tắc thực hiện mv
tươ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
-type f
chỉ 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
.
-L
tham số
-i
là tiêu chuẩn, -t
chỉ 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)
-t
không tồn tại trên một số hệ thống (như AIX không cổ xưa)
find . -type f -mindepth 2 -exec mv {} ./ \;
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ó mv
thay 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 xargs
và với GNU mv
có shell printf
được dựng sẵn (hầu hết, mksh
là ngoại lệ đáng chú ý):
printf '%s\0' ./*/* | xargs -r0 mv -t .
zsh
trườ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 *
.
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)
find
gì cả. Vừa đủ echo
hoặcprintf
find
không giải quyết vấn đề mà xargs
làm.
t
có thể là "mục tiêu"?