Đổi tên nhiều tệp với tên được đánh số phức


6

Tôi có 365 tệp có tên

MOD11A1.A2010001.h24v06.006.2016025150444.hdf
MOD11A1.A2010002.h24v06.006.2016025151748.hdf
MOD11A1.A2010003.h24v06.006.2016025163706.hdf

và tôi muốn đổi tên các tệp này thành:

modis1.hdf
modis2.hdf
modis3.hdf

Tôi đang sử dụng mvlệnh riêng cho từng tệp để đổi tên chúng.

Làm thế nào để tôi đạt được điều này trong một lần?


1
Bạn lấy số trong tập tin được đổi tên từ đâu? Có phải ở cuối .A2010001.một phần của tên tệp gốc? Có khả năng bất kỳ chuỗi số nào trong số này sẽ có giá trị trùng lặp không?
Arronical

.A2010001 ... .A2010365 dành cho 1 ... 365 tệp.
Vaishali Jain

2
Nếu toàn cầu MOD*.hdfkhông trả về bất kỳ kết quả nào, tên tệp của bạn không được ở định dạng bạn đã nêu hoặc bạn không ở trong thư mục chứa các tệp.
Arronical

1
Câu hỏi mà Zanna hỏi vẫn chưa được OP trả lời và điều này rất quan trọng vì nó sẽ thay đổi câu trả lời được đề xuất. Câu hỏi tôi có là liệu số 1 đến 365 trong .A2010001 ... A2010365 phải được sử dụng trong tên tệp mới. Nếu vậy, câu trả lời được đề xuất dưới đây sẽ không đủ.

2
Đó không phải là số phức , chỉ là số nguyên cũ đơn giản!
ilkkachu

Câu trả lời:


10

Vì bạn chỉ quan tâm đến A2010... bit, sử dụng renametrong thư mục với các tệp:

rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' *

Thí dụ:

$ rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' *
rename(> MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis1.hdf)
rename(> MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis2.hdf)
rename(> MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis3.hdf)
rename(> MOD11A1.A2010365.h24v06.006.2016025150444.hdf, modis365.hdf)

Chạy mà không -nthực sự đổi tên các tập tin.


Làm thế nào để (\ d +) nắm bắt các số? Có phải ma thuật regex?
Arronical

4
@Arronical \dlà bất kỳ chữ số nào trong Perl regex, ()là nhóm bắt giữ và phần trước 0*lấy tất cả các số 0 đứng đầu
muru

Thật kỳ diệu, cảm ơn vì đã mở rộng kiến ​​thức của tôi như mọi khi!
Arronical

@Arronical \dđơn giản là một tốc ký [0-9], những tốc ký đó được hỗ trợ khá phổ biến - để xem chi tiết hơn- expressions.info .
tráng miệng

1
@dPlay phổ biến là một chút quá rộng, sedawkkhông, grepcần -P(đối với RE tương thích với Perl) ...
muru

6

Cách sau đây sử dụng mở rộng tham số bash, nhưng nó dựa vào tên tệp của bạn theo đúng định dạng bạn đã nêu vì nó phụ thuộc vào vị trí của chuỗi số sẽ được sử dụng. Đây không hẳn là phương pháp mạnh mẽ nhất. Bạn cũng phải ở trong thư mục chứa các tập tin.

for f in MOD*.hdf; do
  num="${f:13:3}"
  mv "$f" modis"$((10#$num))".hdf
done

Hoặc như một lớp lót:

for f in MOD*.hdf; do num="${f:13:3}"; mv "$f" modis"$((10#$num))".hdf ; done

Điều này sẽ di chuyển các tập tin theo cách mà bạn đã yêu cầu, ý nghĩa rằng MOD11A1.A2010001.h24v06.006.2016025150444.hdfsẽ trở thành modis1.hdf, MOD11A1.A2010002.h24v06.006.2016025151748.hdftrở thành modis2.hdf, vv


Chỉ cần lưu ý rằng bạn đã xóa cú pháp tô sáng về mục đích - tôi có thể hỏi tại sao không? Ý kiến ​​của cộng đồng về điều này dường như khá rõ ràng
món tráng miệng

6

Bạn có thể sử dụng renamelệnh như thế này:

$ rename -n 's/MOD11A1\.A2010(...)\..*/modis$1.hdf/' MOD*.hdf
rename(MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis001.hdf)
rename(MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis002.hdf)
rename(MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis003.hdf)

Sau khi thử nghiệm, loại bỏ -nđể thực sự đổi tên tập tin.

Ghi chú

  • s/old/newthay thế oldbằngnew
  • \. nghĩa đen .
  • ... ba nhân vật có thể là bất cứ điều gì
  • (some chars)lưu lại some charsđể tham khảo sau với$1
  • Chúng ta có thể sử dụng một biểu thức chính đơn giản để khớp với phần đầu tiên của tên tệp trong renamelệnh, như câu trả lời của muru. Đôi khi bạn muốn sử dụng một biểu thức rõ ràng hơn để phân biệt giữa các tệp mà bạn làm hoặc không muốn hành động hoặc để chắc chắn rằng regex của bạn sẽ không hút quá nhiều ký tự. Thường có rất nhiều sự linh hoạt trong việc giải quyết loại vấn đề này.

Lưu ý rằng điều này không cung cấp cho bạn chính xác những gì bạn yêu cầu; nó duy trì chiều rộng cố định của các con số. Tôi đã làm điều này bởi vì đó là một ý tưởng tốt để sử dụng các số có chiều rộng cố định trong tên tệp (nếu không chúng sẽ được sắp xếp theo cách khó hiểu, ví dụ như 10 trước 2) (vàbởi vì tôi chưa tìm ra cách sử dụng renameđể tạo ra tên bạn thực sự yêu cầu ... nếu tôi làm, tôi sẽ cập nhật câu trả lời của mình câu trả lời của muru làm điều đó ...).

Lưu ý rằng Perl renamekhông được bao gồm trong cài đặt 17.10 mặc định , vì vậy nếu bạn đang chạy 17.10 (hoặc cho các độc giả tương lai, có lẽ là phiên bản mới hơn), hãy bắt đầu bằng cách chạy

sudo apt install rename

5

Đoạn mã dưới đây sẽ làm như sau:

  1. lặp trên tất cả các tệp bắt đầu bằng MODvà kết thúc bằng.hdf
  2. Gán một biến, sẽ tăng giá trị của nó trong 1 cho mỗi tệp
  3. thực hiện mvlệnh trên tệp hiện tại trong danh sách và thay đổi tên của nó để modistheo số từ biến, theo sau.hdf

    #!/bin/bash 
    idx=1
    for file in MOD*.hdf
    do
        echo mv "$file" "modis$((idx++)).hdf"
    done
    

Lưu ý: tập lệnh trên sẽ chỉ echothực hiện lệnh mà nó dự định thực hiện, bạn sẽ cần xóa lệnh echokhỏi echo mvdòng để thực hiện hành động hành động.

Đầu ra mẫu:

mv MOD11A1.A2010001.h24v06.006.2016025150444.hdf modis1.hdf
mv MOD11A1.A2010002.h24v06.006.2016025151748.hdf modis2.hdf
mv MOD11A1.A2010003.h24v06.006.2016025163706.hdf modis3.hdf

mv: không thể stat 'MOD * .hdf': Không có lỗi tập tin hoặc thư mục như vậy được hiển thị trong thiết bị đầu cuối.
Vaishali Jain

Làm thế nào để sử dụng lệnh đổi tên để đạt được mục đích của tôi?
Vaishali Jain

1
@VaishaliJain - bạn đã thực thi các dòng mã trên, trong thư mục thực sự chứa các tệp MOD11A1 ...?
Yaron

@VaishaliJain - mvlà mộtrename command
Yaron

@ pa4080 cảm ơn bình luận của bạn! Sẽ cập nhật câu trả lời của tôi khi tôi ở gần máy tính.
Yaron
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.