Cách sao chép tất cả các thư mục chứa một tệp cụ thể


17

Tôi chỉ muốn sao lưu các thư mục nhạc FLAC của mình. Các tệp FLAC có thể được lồng như thế trong các thư mục:

AlbumName/
├── Files/
│   ├── someSong01.flac
│   ├── someSong02.flac
├── Covers/
│   ├── someCover01.jpg
│   └── someCover02.jpg

Làm cách nào để sao chép và di chuyển tất cả các thư mục của AlbumName với cấu trúc và nội dung tương ứng của chúng có chứa một nơi nào đó bên trong ít nhất một tệp FLAC (Tôi cho rằng điều này là đủ để nói: nhạc có định dạng FLAC)

EDIT: Các tệp FLAC có thể được lồng nhau; vì vậy tôi có thể có:

AlbumName2/
├── someSong01.flac
├── someSong02.flac
├── Covers/
│   ├── someCover01.jpg
|   └── someCover02.jpg

Và tôi muốn sao chép các thư mục đó với tất cả nội dung của chúng, không chỉ các tệp FLAC và dán vào thư mục khác.

Vì vậy, nếu tôi có là tốt

AlbumName3/
├── someSong01.mp3
├── someSong02.mp3
├── Covers/
│   ├── someCover01.jpg
|   └── someHiddenSong.flac

AlbumName4/
├── Files/
│   ├── someSong01.mp3
│   ├── someSong02.mp3
├── Covers/
│   ├── someCover01.jpg
│   └── someCover02.jpg

Tôi muốn cp đệ quy sang thư mục khác AlbumName, AlbumName2 và AlbumName3 nhưng không phải AlbumName4

EDIT: Không có câu trả lời nào thực sự làm những gì tôi muốn, vì vậy tôi đã kết thúc bằng cách sử dụng một cái gì đó như thế:

 find -mindepth 2 -name '*.flac' -exec dirname {} \; | awk -F "/" '{print $2}' | sort -u | while read -r dirname; do cp -r "$dirname" "backup/"; done

về cơ bản tôi liệt kê tất cả các tập tin flac, tôi lấy thư mục gốc bằng awk, tôi xóa các bản sao và tôi làm những gì tôi muốn


Sao lưu đến đâu, đích đến của bạn là gì?
George Udosen

Chỉ các tệp flac cần được sao chép hoặc toàn bộ các thư mục có ít nhất một tệp flac?
không ai có

@nobody thư mục: " Làm cách nào để sao chép và di chuyển tất cả các thư mục của AlbumName với cấu trúc và nội dung tương ứng chứa ở đâu đó bên trong ít nhất một tệp FLAC "
terdon

Câu trả lời:


19

Một tùy chọn là sử dụng rsync, chỉ sao chép các tệp flac và giữ nguyên cấu trúc thư mục:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • một kho lưu trữ
  • dài dòng
  • nén z trong khi chuyển (có thể không hữu ích sao chép trên cùng một máy tính)
  • m prune trống dirs
  • đầu tiên bao gồm tất cả các thư mục
  • thứ hai bao gồm các tập tin flac
  • loại trừ cuối cùng loại trừ tất cả các tệp khác

Có thật không? Tôi hiểu, anh muốn bảo tồn cấu trúc thư mục. Anh ấy nói: "Làm cách nào để sao chép và di chuyển tất cả các thư mục của AlbumName với cấu trúc và nội dung tương ứng của chúng ...".
không ai có

2
Ồ, tôi hiểu rồi. Tôi không chắc. Chỉ các tệp flac cần được sao chép hoặc toàn bộ các thư mục có ít nhất một tệp flac?
không ai có

Câu hỏi được chỉnh sửa và bây giờ nó giải thích chi tiết hơn, những gì fricadelle muốn. Đưa vào tài khoản rằng tất cả nội dung sẽ được sao chép, nếu có tệp flac, câu trả lời của tôi là sai vì nó chỉ sao chép các tệp flac. Tuy nhiên nó vẫn có thể hữu ích cho một số mục đích khác.
không ai có

9

chào bạn của tôi, bạn có thể sử dụng

mkdir newdirectory
cp -r --parents */*.flac newdirectory/

2
Đẹp chưa từng sử dụng --parentstrước đây!
George Udosen

4
Hãy giải thích điều này */*.flac! Sẽ cp -r --parents AlbumName/ newdirectory/không đủ?
George Udosen

3
Từ câu hỏi, có vẻ như các flac có thể có hoặc không có trong các thư mục lồng nhau, vì vậy tôi khuyên bạn nên kích hoạt globalstar ( shopt -s globstar), sau đó sử dụng **/*.flaccho toàn cầu. Sao đôi sẽ khớp với 0 hoặc nhiều thư mục.
wjandrea

bạn hoàn toàn đúng wjandrea, hãy để tôi chỉnh sửa câu hỏi của mình để mọi người hiểu
fricadelle

5

Câu trả lời hay

Tôi muốn thêm một cách nữa, bạn cũng có thể sử dụng kết hợp tìmcpio

find . -name "*.flac" -print0|cpio --null -pdm destination/

Giải trình:

GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to the rules of precedence (see Operators), until the outcome is known (the left-hand side is false for AND operations, true for OR), at which point find moves on to the next file name.

GNU cpio is a tool for creating and extracting archives, or copying files from one place to another. It handles a number of cpio formats as well as reading and writing tar files.

Có 3 chế độ cpio:

  • Chế độ sao chép: In copy-out mode, cpio copies files into an archive. It reads a list of filenames, one per line, on the standard input, and writes the archive onto the standard output.

  • Chế độ sao chép: In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input.

  • Chế độ sao chép: In copy-pass mode, cpio copies files from one directory tree to another, combining the copy-out and copy-in steps without actually using an archive. It reads the list of files to copy from the standard input; the directory into which it will copy them is given as a non-option argument.

Ở đây, chúng tôi đang sử dụng chế độ Copy-pass.

  • Tùy chọn Được sử dụng trong lệnh trên:

tìm thấy:

  • -name -> tên tệp hoặc sử dụng regex thay vì viết tên đầy đủ

cpio:

  • '-m, --preserve-sửa đổi-thời gian' Retain previous file modification times when creating files.
  • '-p, - xuyên qua' Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, --make-thư mục' Create leading directories where needed.'
  • --quiet' Không in số lượng khối được sao chép.

New options are the "-print0" available with GNU find, combined with the "--null" option of cpio. These two options act together to send file names between find and cpio, even if special characters are embedded in the file names.

Người ta cũng có thể sử dụng rsynchoặc viết một tập lệnh shell để tìm và sao chép các tệp có cấu trúc thư mục.

Để được giải thích về Rsync, vui lòng xem các câu trả lời ở trên.


2
Bạn có thể cải thiện câu trả lời của mình bằng cách giải thích các lệnh và các tùy chọn bạn đề xuất. - Từ đánh giá
J. Starnes

@dPlay yeah, đúng rồi. Cảm ơn bạn, cho đề nghị hoàn hảo của bạn.
bsdboy

4

Trả lời 1: Bạn cũng có thể sử dụng findlệnh cho cùng.

mkdir newDir && find AlbumName/ -iname "*.flac" -exec cp --parents "{}" newDir/ \;

Giải thích:

mkdirtạo thư mục mới. findlệnh tìm *.flactập tin nằm trong AlbumNamethư mục. execlệnh thực thi cplệnh cho mỗi tên tệp findđã trả về.

Trả lời 2: Bạn cũng có thể sử dụng findlệnh với xargscũng

mkdir newDir && find AlbumName/ -iname "*.flac" | xargs -I{} cp --parents {} newDir/

Thêm thông tin: tìm , xargs


1
find | xargssẽ phá vỡ tên tập tin có dấu cách, thay find -print0 | xargs -0vào đó sử dụng .
tráng miệng

tôi đã thử với 1 2.flactập tin có không gian trong tên tệp. Bạn có thể vui lòng cho tôi biết tên tập tin find | xargsthất bại không?
mf_starboi_8041


Tôi không biết nhưng tôi có thể sao chép tệp có tên dài có không gian chứa trong đó mà không cần sử dụngfind -print0 | xargs -0
mf_starboi_8041

Hãy thử touch "a space" && find . | xargs ls.
tráng miệng

0

Chỉ cần giải quyết vấn đề tương tự cho thư viện nhạc của tôi và giải quyết nó bằng cách sử dụng tập lệnh phù hợp sau đây. Tôi đã không hoàn toàn thiết kế nó với các biến tức là, vì tôi chỉ có ý định sử dụng nó một lần :).

Kịch bản di chuyển mọi thư mục chứa các tệp flac bao gồm tất cả các tệp và thư mục con khác đến một vị trí mới bằng rsync. rsync cho phép bạn tiếp tục tập lệnh nếu nó dừng trong quá trình.

Cấu trúc thư viện của tôi:

library
|-artist
  |- album 1 (mp3)
  |- album 2 (flac)

Cấu trúc thư viện mới:

library
|-artist
  |- album 1 (mp3)

library-lossless
|-artist
  |- album 2 (flac)

(1) bắt đầu tập lệnh shell sau trong đích SOURCE (thay thế TARGET bằng thư mục tương ứng bạn chọn - Tôi chỉ sử dụng đường dẫn tuyệt đối)

hàng 1: tìm tất cả các thư mục chứa tệp flac và pipe (|) vào
hàng 2: loại bỏ trùng lặp với sort và pipe liệt kê vào
hàng vòng lặp do 3: cho mỗi thư mục làm
hàng 4: hiển thị thư mục trong
hàng xử lý 5: rsync vào thư mục đích cộng với xóa nguồn và bảo toàn cấu trúc (-R) trong
hàng vị trí đích 6: xóa thư mục trống (vì rsync chỉ xóa các tệp)

find . -type f -name \*.flac -printf "%h\n" | 
sort -u | 
while read -r dirname; do
    echo $dirname
    rsync -azvm -R --remove-source-files "${dirname}" TARGET
    find "${dirname}" -type d -delete
done

(2) sau khi thực hiện thành công tập lệnh trong (1), bạn có thể thực thi lệnh sau trong thư mục nguồn

find . -depth -type d -empty -delete

Lệnh này xóa tất cả các thư mục trống không bị xóa trong tập lệnh. Tức là các thư mục "Artist", trong đó tất cả các thư mục con / album bao gồm các tệp flac.

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.