Làm cách nào để đổi tên nhiều tệp liên tục từ dòng lệnh?


15

Cách đổi tên tập tin như dưới đây

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

sang tên mới

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt

Câu trả lời:


22

Công renamecụ đi kèm với Ubuntu khá hấp dẫn với loại công cụ này. Bạn có thể nhúng các biểu thức Perl nhỏ như vậy:

rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *

Điều đó sẽ chỉ cho bạn thấy những gì nó sẽ làm. Loại bỏ -nđể làm cho nó một bài tập lửa sống.

Điều này về cơ bản hoạt động bằng cách xác định sơ bộ một biến và tăng nó cho mỗi tệp chúng ta nhấn. Nếu bạn sẽ có nhiều hơn 10 tệp, tôi khuyên bạn nên sử dụng một số phần đệm không trong sprintf. Sau đây là tốt lên đến 999:

rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *

... Nhưng nó đủ dễ để mở rộng.


4

Tôi không biết một lệnh hoặc tiện ích duy nhất sẽ làm điều này, nhưng nó đủ dễ thực hiện với một vòng lặp đơn giản:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done

3

Để cải thiện câu trả lời của @ Oli's , phiên bảnrename công cụ 1.600 của Aristotle Pagaltzis thực sự có một bộ đếm được tích hợp sẵn $N.

Vì vậy, tất cả những gì bạn cần là,

rename 's/AS.*/AS$N/' *

Để cài đặt,

  1. brew install renamehoặc Tải xuống tập lệnh
  2. Lưu nó vào một thư mục trên đường dẫn hệ thống của bạn (thường /usr/local/bin/brewhoặc /usr/bin)

3
Đây dường như là một công cụ khác có cùng tên. Mặc định của Ubuntu renamelà tên. Điều này có thể tốt hơn nhưng bạn có thể muốn thêm hướng dẫn cài đặt để làm cho câu trả lời này có giá trị hơn.
Oli

1
@Oli gọi tốt! cập nhật.
Atav32

2

renamecho phép bạn chỉ định trực tiếp $_, đó là lý tưởng cho vấn đề này.

Mặc dù các đối số mã mà chúng tôi chuyển đến renametiện ích Perl thường thực hiện khớp và thay thế (bằng s/) và hoàn toàn có thể chấp nhận để giải quyết vấn đề này theo cách đó , nhưng thực sự không cần thiết trong trường hợp như thế này khi bạn không thực sự kiểm tra hoặc sử dụng lại văn bản của tên tập tin cũ. renamecho phép bạn viết bất kỳ mã Perl nào và không cần phải nhúng vào bên trong s/ /e. Tôi đề nghị sử dụng một lệnh như thế này:

rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *

Hoặc, nếu bạn cảm thấy muốn cạo sạch một vài ký tự:

rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *

(Nó có thể được thực hiện thậm chí ngắn hơn, nhưng không phải không hy sinh sự rõ ràng.)

Cả hai lệnh này đều làm điều tương tự. Mỗi chương trình cho thấy các hoạt động đổi tên sẽ được thực hiện. Khi bạn thử một lần và bạn hài lòng với kết quả, hãy chạy lại mà không có -ntùy chọn. Theo văn bản, điều này sẽ tạo ra tên tập tin AS01.txt, AS02.txt, ..., AS10.txt, AS11.txt, và vân vân. Bạn có thể sửa đổi chúng khi cần, sau đó chỉ xóa -nkhi bạn thích những gì bạn thấy.

Nếu bạn muốn đệm đến chiều rộng lớn hơn 2, hãy thay thế 2bằng số lớn hơn. Ví dụ: nếu vì lý do nào đó bạn muốn tên tệp như thế AS00000000000001.txt, bạn sẽ thay thế %02dbằng %014d. Nếu bạn hoàn toàn không muốn đệm - mặc dù điều đó sẽ làm cho các tệp của bạn xuất hiện theo thứ tự không phải là số khi bạn liệt kê chúng sau! - thì bạn có thể thay thế %02dbằng %d.

Cái này hoạt động ra sao? Shell của bạn mở rộng * thành một danh sách các tập tin trước khi nó chạy renamelệnh. Danh sách được sắp xếp theo từ vựng (nghĩa là theo thứ tự abc) theo cài đặt ngôn ngữ hiện tại của bạn. renamenhận tên tệp dưới dạng đối số dòng lệnh và xử lý chúng theo thứ tự chúng được liệt kê. Biểu thức ++$iước tính lớn hơn một giá trị hiện tại của biến $ivà cũng đặt biến $iđó thành giá trị mới tăng. Giá trị này được chuyển đến sprintf, định dạng nó và đặt nó bên trong văn bản khác. Văn bản này được gán trực tiếp cho biến đặc biệt $_, chứa tên tệp. Vì các renametệp quy trình theo thứ tự chúng được truyền dưới dạng đối số, nên chúng được đánh số tương ứng.


Bạn có thể nhận thấy sự tương đồng với câu trả lời của Oli's !

Cả hai đều khai báo và tăng một biến đếm và cả hai đều sử dụng sprintfvề cơ bản giống nhau để nhúng giá trị của bộ đếm đó, được đệm bên trái bằng các số không, trong văn bản khác của tên tệp mới. (Thông tin trong một trong hai câu trả lời về cách pad với số không - và thay đổi chiều rộng padding -. Thậm chí áp dụng đồng đều cho cả hai) Lý do họ là như vậy tương tự là phương pháp trong đó câu trả lời cũ đang thực sự làm chỉ này 1 , nhưng với các bước bổ sung hữu ích cho nhiều vấn đề nhưng không thực sự cần thiết cho vấn đề này.

Để so sánh, đây là lệnh thứ hai trong câu trả lời đó trông như thế nào nếu được sửa đổi để sử dụng kiểu tôi đã sử dụng ở đây (và để tăng lên 2 chiều rộng, như tôi đã làm ở đây, thay vì 3):

rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *

Phần giữa s/.+//etrong lệnh đó bây giờ giống như biểu thức tôi gán cho $_(nghĩa là mã ở phía bên phải của =toán tử) trong lệnh đầu tiên trong câu trả lời này.

  • Các s/ nhà điều hành những nỗ lực để văn bản phù hợp (tên tập tin mà vỏ của bạn mở rộng từ *và thông qua như là đối số dòng lệnh khi nó chạy rename) với một biểu thức chính quy , và thay thế thực hiện. /đang được sử dụng như một dấu phân cách để phân tách các phần khác nhau của sbiểu thức. Phần đầu tiên .+, là biểu thức chính quy; nó phù hợp với bất kỳ 1 ký tự ( .) và thực hiện một hoặc nhiều lần ( +) . Vì tên tệp không bao giờ trống - chúng luôn dài ít nhất một ký tự - đây là một cách để khớp với bất kỳ 1 tên tệp nào.
  • Sau đó, nó tạo ra văn bản từ mỗi trận đấu - có nghĩa là, từ mỗi cả tên tập tin - bao gồm our $i; sprintf "AS%02d.txt", ++$i. Điều này tạo ra tên tệp mới. Thông thường, người ta sử dụng s/để tạo văn bản là (a) thay thế văn bản chỉ khớp với một phần của tên tệp hoặc (b) dựa trên văn bản phù hợp theo một cách nào đó (ví dụ: nó có thể sử dụng một biến đặc biệt như $&mở rộng ra trận đấu). Tuy nhiên, trong trường hợp này, văn bản phù hợp hoàn toàn không được sử dụng.
  • Thông thường văn bản thay thế our $i; sprintf "AS%02d.txt", ++$isẽ được sử dụng làm tên tệp, không chạy dưới dạng mã. Nhưng /ecờ ở cuối khiến văn bản đó được coi là mã nguồn Perl và được đánh giá và sử dụng giá trị được tạo ra bằng cách đó (trong trường hợp này, giá trị trả về của sprintfhàm dựng sẵn của Perl ) làm tên tệp mới.

Mặc dù tôi nghĩ rằng phương pháp tôi đã đưa ra ở đây là một cách tiếp cận rõ ràng và đơn giản cho vấn đề này hơn bất cứ phương pháp mà sử dụng s/với /e, nó tốt đến mức khó nhận thức kỹ thuật mà, bởi vì nó cũng là phù hợp với một số đổi tên vấn đề tập tin khác, nơi tất cả hoặc một phần tên tệp gốc được kiểm tra và / hoặc giữ lại. Tôi đề nghị bài đăng trên blog này của Oli (người cũng đã viết câu trả lời đó ), trong đó bao gồm một số ví dụ như vậy.

1 Về mặt kỹ thuật, có một sự khác biệt trong hành vi của các $_ =lệnh và các s/ /elệnh. Trong biểu thức chính quy .+, nó không hoàn toàn đúng .với bất kỳ ký tự nào , vì nó không khớp với một dòng mới . Bạn rất có thể không nên sử dụng tên tệp có dòng mới trong đó, nhưng bạn có thể, và đôi khi một tệp được đặt tên theo cách đó một cách tình cờ. Nếu bạn cảm thấy thích nó, tương phản đầu ra của rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'. Để .khớp với một dòng mới, sử dụng scờ ở cuối (với e). Đó là, viết /seở cuối thay vì /e.


0

Giả sử các tệp bạn muốn đổi tên nằm trong ~/Adirvà đây là các tệp duy nhất trong thư mục này, sau đó:

n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done

Kịch bản lệnh này sẽ xem xét từng tệp ~/Adirvà đổi tên thành AS1.txt, AS2.txt, ...nếu tệp không tồn tại (sẽ không có bất kỳ ghi đè nào). Đó là lý do tại sao bạn nên đảm bảo đây là những tệp duy nhất ~/Adir. Các sortlệnh là chỉ trong trường hợp bạn muốn các tập tin để giữ trật tự ban đầu.


0

Mặc dù OP yêu cầu tùy chọn dòng lệnh, nó cũng có sẵn dưới dạng tùy chọn GUI trong Nautilus và khá dễ dàng.

Chọn tất cả các tập tin cần thiết và nhấn F2. Có một tùy chọn gọi là Số tự động. Bạn có thể nối nó vào văn bản mà bạn cần.

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.