Đổi tên hàng loạt các tệp bằng biểu thức chính quy trong Unix


2

Tôi có vài ngàn tệp có dạng:

[Số có 8 chữ số] _ [số tôi muốn] _S60491_I129111.dcm.

Tôi muốn xóa mọi thứ trừ số tôi muốn và sử dụng nó làm tên của nó. Trong Ruby, tôi có thể nhận được giá trị đó bằng biểu thức chính quy /^.*_(\d+)_S60491_I12911.dcm/, nhưng tôi gặp khó khăn khi cố dịch nó thành sedbiểu thức cho phép tôi thay thế tên tệp đầy đủ cho chỉ số đó giữa các dấu gạch dưới.

Có cách nào sử dụng sedhoặc các lệnh Bash cơ bản khác để làm những gì tôi muốn không? Nếu nó giúp, số tôi muốn chỉ là một bộ đếm (tức là nó chạy từ 1 đến 2100) và số 8 chữ số tiền tố xảy ra dẫn đến các tệp được liệt kê theo đúng thứ tự (ví dụ: từ tệp 1 đến tệp 2100), Vì vậy, tôi có thể suy nghĩ quá nhiều thứ.

Câu trả lời:


1

Điều này làm việc cho tôi: for a in * ; do mv "$a" $(echo "$a" | cut -d'_' -f 2) ; done

con cóc: / nhà / hennes / công việc / foo> ls -l
tổng 0
-rw ------- 1 người dùng 0 ngày 23 tháng 1 22:19 12345678_023454_S60491_I129111.dcm
-rw ------- 1 người dùng 0 ngày 23 tháng 1 22:19 12345678_123454_S60491_I129111.dcm
-rw ------- 1 người dùng 0 ngày 23 tháng 1 22:19 12345678_123456_S60491_I129111.dcm

cóc: / nhà / hennes / công việc / foo> cho một trong *; làm mv $ a $ (echo $ a | cut -d'_ '-f 2); làm xong

con cóc: / nhà / hennes / công việc / foo> ls -l
tổng 0
-rw ------- 1 người dùng 0 tháng 1 23 22:23 023454
-rw ------- 1 người dùng 0 tháng 1 23 22:23 123454
-rw ------- 1 người dùng 0 tháng 1 23 22:23 123456

for a in *chọn tất cả các tập tin Nếu có nhiều tệp hơn, một * .dcm có thể được sử dụng thay thế.

mv (di chuyển) thay đổi tên tệp

từ $ a (tên tệp chọn trong)

đến trường2 của tên, với _một dấu phân cách trường được sử dụng.

Lưu ý rằng tập lệnh này sẽ di chuyển các tệp, vì vậy tên tệp cũ sẽ bị mất. Bạn có thể sử dụng 'cp' thay vì 'mv' để tạo một bản sao thay thế.

Nếu bạn muốn giữ phần mở rộng thì hãy thêm nó sau -f 2).
Ví dụ for a in * ; do cp $a $(echo $a | cut -d'_' -f 2).dcm ; done


2

Có một công cụ thường được đặt tên là đổi tên hoặc prenamecài đặt trên hầu hết các hệ thống. Trên các hệ thống Debian / Ubuntu của tôi, đây là một phần của Perl. Nó cho phép bạn sử dụng các biểu thức chính quy theo kiểu Perl để thao tác tên tệp theo cách bạn muốn.

Lệnh của bạn có thể sẽ trông như thế này. Tôi khuyên bạn nên vượt qua --no-acttùy chọn và kiểm tra đầu ra trước khi bạn thực sự cam kết thực hiện bất kỳ thay đổi nào.

prename 's/^.*_(\d+)_S60491_I12911.dcm/$1/' *

Tôi đã tìm thấy renameprenamexuất hiện một chút khi cố gắng tự tìm kiếm giải pháp, nhưng thật không may là nó dường như không có trên máy chủ tại nơi tôi đang sử dụng cho việc này (có vẻ như đó là phiên bản của Red Hat). Chắc chắn một cái gì đó tôi sẽ tìm đến trên máy tính nhà của tôi mặc dù.
ackrause

Nó là một kịch bản perl khá đơn giản. Bạn gần như chắc chắn có thể lấy một bản sao từ một số hộp khác, nếu bạn đã cài đặt Perl.
Zoredache

1

Vì chúng tôi biết định dạng của tên và không có khoảng trắng:

for a in * ; do
   mv $a $(echo $a | sed 's/[^_]*_//;s/_S60491_I129111.dcm//')
done

Xin lỗi về chỉnh sửa / rollback, tôi thấy điều này sẽ phá vỡ không gian nhưng bỏ qua từ chối trách nhiệm của bạn.
terdon

0

Có nhiều cách để thực hiện điều này. Nhưng vì bạn đã yêu cầu sed, điều này sẽ làm:

ls dcm | sed 's / ^ ([0-9] {8} _ ([0-9] ) _S60491_I129111.dcm) / mv \ 1 \ 2 / g' | bash

Bit đầu tiên của mẫu chọn các số có 8 chữ số, sau đó bạn tìm bất kỳ chữ số nào (vì bạn không đề cập đến kích thước của số thứ hai) và sau đó là chuỗi theo dõi của bạn. \1\2tham khảo nội dung của dấu ngoặc đơn thoát bên ngoài và bên trong \(...\). Bạn có thể thay thế bashbởi bất kỳ vỏ trong trường hợp này.

Các phần mở rộng GNU của sed sẽ cho phép bạn thực hiện:

ls * dcm | sed 's / ^ ([0-9] {8} _ ([0-9] +) _ S60491_I129111.dcm) / mv \ 1 \ 2 / g' | bash

trong đó +cho phép khớp một hoặc nhiều, trong đó *khớp từ 0 trở lên, điều này gây ra sự cố cho 12345678__S60491_I129111.dcm.

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.