Cố gắng thực hiện số học trong công cụ đổi tên Perl (Debian)


8

Giả sử tôi có năm tệp mp3:

01-trackfoo.mp3
02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
05-trackxyz.mp3

Bây giờ tôi nghe nhanh các tập tin (chỉ cần mplayer trên bàn điều khiển sẽ thực hiện thủ thuật) và tôi phát hiện ra rằng các bản nhạc không đúng thứ tự . 05 thực sự là 02 và phần còn lại sẽ phải đổi tên. Vì vậy, trước tiên tôi sẽ thực hiện đổi tên tạm thời:

01-trackfoo.mp3

02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
00-trackxyz.mp3

Bây giờ chúng ta cần một "ca": 02 nên trở thành 03, 03 nên trở thành 04 và 04 nên trở thành 05. Để giảm thiểu nhầm lẫn, ex-05 (bây giờ 00) sẽ chỉ là mved sau.

Cách tiếp cận của tôi là thế này: (perl rename, bởi Larry Wall, mặc định ở đây trên Debian)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/' *

cũng như (sau này, sau một số RTFM'ing nữa)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/e' *

Không ai trong số họ làm việc, đặc biệt là vì công cụ /e[val]sửa đổi không chấp nhận bất cứ điều gì khác ngoài các đánh giá và sẽ đưa ra lỗi khi bạn cố gắng kết hợp các đánh giá với chuỗi. Có bashthể làm điều đó tốt, ví dụ foo$((1+6))sẽ được đánh giá foo7.

Vậy làm thế nào tôi có thể làm điều này (ưu tiên một lớp, không có ý định viết toàn bộ tập lệnh độc lập chỉ cho việc này)?

Câu trả lời:


7

Bạn gần như đã có nó. Bạn chỉ cần làm cho chuỗi ký tự và nối chuỗi rõ ràng trong /ethay thế -modified, sử dụng dấu ngoặc kép và toán tử dấu chấm.

rename 's/0([2-4])([\s\S]+)/"0".($1+1).$2/e' *

Nó để lại 05 gốc vẫn chưa được đổi tên, nhưng +1 để giải quyết trục trặc một lớp .
Peter.O

1
(nhỏ lưu ý, đổi tên được gọi prename trong Ubuntu) ... Nếu không có tên trong danh mục bắt đầu với $'\x01'2sau đó một đổi tên ban đầu như thế này: prename 's/^05/\x012/' 05*.. sau đó ở trên [2-4]đổi tên .. sau đó một trận chung kết prename 's/^\x01/0/' $'\x01'2*sẽ làm các trick .. Điều đó làm cho 3 một -liners ... Trong lần thứ tư và kiểm tra ban đầu về sự hiện diện có thể có của một tệp bắt đầu $'\x01', một đoạn như bash này sẽ bẫy nó ..shopt -s nullglob; x=($'\x01'*); [[ -n $x ]] && { echo '\x01' is not suitable; exit; }
Peter.O

YEEES! Cảm ơn Alan, tôi đã không nghĩ về toán tử dấu chấm đó, mặc dù tôi đã biết phải làm gì bằng những từ có thể đọc được của con người: "nói / e đừng chạm vào những thứ bên ngoài ()" :) Và cảm ơn Peter vì bash cách tiếp cận là tốt. Ngoài ra, nếu tôi có bất kỳ ý tưởng nào về việc cú pháp PHP gần với Perl như thế nào , có lẽ tôi đã tìm ra giải pháp bằng cách dùng thử - và lỗi. Bởi vì dấu chấm đó là đối tác JavaScript '+' trong PHP để nối chuỗi.
cú pháp

4

ưu tiên một lớp, không có ý định viết toàn bộ tập lệnh độc lập chỉ cho việc này

Khi mọi thứ trở nên phức tạp, tôi không thấy bất kỳ lý do nào để không viết kịch bản. Bạn sẽ không bao giờ nhớ làm thế nào để thực hiện việc này từ lần chạy này sang lần chạy tiếp theo, vì vậy cuối cùng bạn sẽ phát minh lại nó hoặc hoàn thành nó trong một kịch bản.

Đối với một điều nhỏ như thế này, tôi thường bắt đầu cố gắng giải quyết nó trong Bash:

#!/bin/bash
if [ -z "$1" ] ; then echo Need arguments. ; exit 1 ; fi

typeset -i i=1
for f in "$*"
do
    tailbits=`echo "$f" | sed -e 's/^[0-9]+//'`
    mv "$f" sertmp-`printf %02d $i`"$tailbits"
    i=i+1
done

for f in "sertmp-*"
do
    mv "$f" `echo "$f" | sed -e s/^sertmp-//` 
done

Về cơ bản, tập lệnh này loại bỏ bất kỳ chữ số hàng đầu nào, sau đó đặt số sê-ri tăng không đệm ở mặt trước, với các tệp được đánh số theo thứ tự bạn chuyển chúng vào tập lệnh.

Nó thực hiện điều này trong hai giai đoạn, với sertmp-tiền tố cho lần đầu tiên vượt qua để tránh mọi rủi ro về va chạm tên. Nếu bạn gọi kịch bản này mp3-renamervà gọi nó như:

$ mp3-renamer 01-foo.mp3 03-bar.mp3 04-qux.mp3

bạn gặp phải một xung đột nhỏ trong lần đổi tên đầu tiên nếu bạn không sử dụng 2 lượt để thực hiện đổi tên. ( 01-foo.mp3-> 01-foo.mp3.)

Nếu bạn gọi nó như thế này, mặc dù:

$ mp3-renamer 02-foo.mp3 01-foo.mp3

bạn vô tình xóa 01-foo.mp3trong lần đổi tên đầu tiên bằng đổi tên 1 lượt.

Nếu vấn đề trở nên phức tạp hơn, tôi sẽ viết lại bằng Perl. Tại thời điểm đó, bạn có thể sử dụng hàm băm để giữ ánh xạ tên cũ-> mới và sử dụng một chút mã thông minh để tìm ra thứ tự thích hợp để thực hiện việc đổi tên nhằm tránh sự cần thiết cho 2 lần vượt qua.

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.