So sánh đệ quy nội dung thư mục theo tên, bỏ qua phần mở rộng tệp


7

Tôi có một thư mục chứa khoảng 7.000 tệp nhạc. Tôi đã sử dụng què để mã hóa lại đệ quy tất cả các tệp trong đó vào một thư mục riêng, xuất ra tất cả các tệp có cùng đường dẫn và tên tệp tương đối. Các tệp đầu ra có phần mở rộng .mp3, nhưng một số tệp đầu vào có các phần mở rộng khác nhau (.wma, .aac, v.v.).

Tôi có thể thấy rằng có sự khác biệt về số lượng tệp ~ 100 tệp bị thiếu trong thư mục đầu ra. Những gì tôi muốn làm là chạy một so sánh của hai thư mục và có được một danh sách các tệp tồn tại trong nguồn, nhưng không phải ở đích. Điều này sẽ đủ đơn giản ngoại trừ tôi cần bỏ qua sự khác biệt trong phần mở rộng tập tin.

Tôi đã thử sử dụng rsync với chế độ chạy khô nhưng tôi không thể tìm ra cách bỏ qua các phần mở rộng tệp. Tôi cũng đã thử diff nhưng không thể tìm thấy tùy chọn chỉ kiểm tra theo tên mà bỏ qua phần mở rộng tập tin. Tôi bắt đầu nghĩ rằng tôi chỉ có thể thực hiện một ls đệ quy trên cả hai thư mục, loại bỏ các phần mở rộng tệp và sau đó so sánh các đầu ra, nhưng tôi thực sự không biết bắt đầu từ đâu với việc sửa đổi đầu ra ls bằng sed hoặc awk.

Câu trả lời:


7

Để xem danh sách, đây là hai biến thể, một biến thể được đệ quy thành các thư mục con và một biến thể không có. Tất cả sử dụng cú pháp cụ thể để bash, ksh và zsh.

comm -3 <(cd source && find -type f | sed 's/\.[^.]*$//' | sort) \
        <(cd dest && find -type f | sed 's/\.[^.]*$//' | sort)
comm -3 <(cd source && for x in *; do printf '%s\n' "${x%.*}"; done | sort) \
        <(cd dest && for x in *; do printf '%s\n' "${x%.*}"; done | sort)

Ngắn hơn, trong zsh:

comm -3 <(cd source && print -lr **/*(:r)) <(cd dest && print -lr **/*(:r))
comm -3 <(print -lr source/*(:t:r)) <(print -lr dest/*(:t:r))

Các commdanh sách lệnh các dòng mà là chung cho hai tập tin ( comm -12), mà chỉ có trong file đầu tiên ( comm -23) hoặc chỉ có trong tập tin thứ hai ( comm -13). Các con số chỉ ra những gì được trừ từ đầu ra¹. Hai tập tin đầu vào phải được sắp xếp.

Ở đây, các tập tin trong thực tế là đầu ra của một lệnh. Shell đánh giá <(…)cấu trúc bằng cách cung cấp một tập tin giả mạo của người Viking (một bộ /dev/fd/mô tả tập tin có tên là FIFO hoặc có tên) làm đối số cho lệnh.

¹ Vì vậy, ở đây những người nói trừ là hoàn toàn hợp lý.


Nếu bạn muốn thực hiện các hành động trên các tệp, có thể bạn sẽ muốn lặp lại các tệp nguồn.

cd source
for x in *; do
  set -- "…/dest/${x%.*}".*
  if [ $# -eq 1 ] && ! [ -e "$1" ]; then
    echo "$x has not been converted"
  elif [ $# -gt 1 ]; then
    echo "$x has been converted to more than one output file: " "$@"
  else
    echo "$x has been converted to $1"
  fi
done

1
+1 cho chú thích đặc biệt (Bạn có phải là tôi không?), Nhưng cũng cho câu trả lời xuất sắc như thường lệ.
Tạm dừng cho đến khi có thông báo mới.
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.