Có một lệnh linux như mv nhưng với regex?


Câu trả lời:


32

Như những người khác đã đề cập, renamerất tốt trong việc này, nhưng hãy đọc trang man ( man rename) trước khi bạn thử nó. Có ít nhất hai công cụ hoàn toàn khác nhau được gọi renamevà công cụ nào bạn có sẽ phụ thuộc vào phân phối của bạn. Gọi họ không chính xác có thể nguy hiểm.

Đây là trang dành cho phiên bản dựa trên perl của Larry Wall đi kèm với Ubuntu. Bạn cho nó một biểu thức perl nhưrename 's/\.sql$/.php/' *.sql

Đây là trang hướng dẫn đổi tên cho các bản phân phối Red Hat và CentOS cũ hơn. Cách sử dụng là thay thế chuỗi đơn giản nhưrename .sql .php *.sql

Bạn cũng có thể sử dụng bash one-liner để xử lý từng tệp một lần:

$ for f in *.sql; do mv -i "$f" "${f%%.*}.php"; done

Ai đó có thể tải lên tệp nhị phân Windows để đổi tên dựa trên perl không?
mcand

Phiên bản Perl đổi tên không thể di chuyển tệp từ hệ thống tệp này sang hệ thống tệp khác.
lilydjwg

bash one-liner rất hữu ích, đặc biệt là khi không có renamechức năng (ví dụ như busybox)
artm

10

rename(1), không sử dụng regexes, nhưng có thể giải quyết vấn đề của bạn:

rename .sql .php *.sql

Cũng có mmv(1), nhưng tôi không quen với cách nó hoạt động.


Trong Ubuntu và Debian (không chắc chắn về các bản phân phối khác), /usr/bin/renamecác liên kết đến /usr/bin/prenametheo mặc định, có regexps.
ℝaphink

5

Ngày mai

Bạn cũng có thể thử nhập

for i in $(\ls -d *.sql)
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

Hoặc để làm cho nó sử dụng regex thay đổi một chút để

for i in $(\ls -d | egrep -e '.*\.sql')
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

cho một chút niềm vui mã hóa vỏ. (-:


2
Điều này không thành công với các tệp chứa khoảng trắng trong tên của chúng, vì vậy hãy cẩn thận. Không bao giờls nên phân tích đầu ra .
slhck

THe sedví dụ là khá tốt, mặc dù.
ngôi sao sáng

2

Là một thợ sửa ống nước, tôi thích đường ống :)

Lưu ý: câu trả lời này dài dòng - vì là một người mới, tôi đánh giá cao nó khi ai đó biết dành thời gian để giải thích, vì vậy tôi đang trả tiền 'chuyển tiếp'. Nếu bạn không phải là người mới, xin vui lòng xin lỗi về độ dài và độ dài.

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/' | bash

Ở đâu:

ls -1 *_201[67][0-9]*

liệt kê tất cả các tệp khớp với mẫu, trong trường hợp này tôi đang tìm các tệp có ngày trong tên tệp ở dạng 'YYYYMMDD'

sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'
#        : | |    |     |                  | |       |                    |:                                 :
#        : |^2....^    ^3..................^^4.......^                    |:                                 :
#        :^1..............................................................^:                                 :
#        /................filename.................pattern................./...mkdir...and....mv...command.../

^ 1: Nhóm chụp thứ nhất - toàn bộ tên tệp

^ 2: Nhóm chụp thứ 2 - phần thứ nhất của mẫu tên tệp

^ 3: Nhóm chụp thứ 3 - phần tên tệp thứ 2 - ở đây, ngày là 'YYYYMMDD'

^ 4: Nhóm chụp thứ 4 - phần tên tệp tùy chọn giữa ngày và tiện ích mở rộng và chính phần mở rộng

Sooooo .... nếu tôi có một tập tin tên

CallLog_555123412_20161231-214403.7z

...sau đó

mkdir -p \2\/\3; mv \1 \2\/\3\/\1

thực sự có nghĩa là

# make directory and sub-directory
mkdir -p CallLog_555123412/20161231
# move file from current directory to sub-sub-directory just created
mv CallLog_555123412_20161231-214403.7z CallLog_555123412/20161231/CallLog_555123412_20161231-214403.7z

Lưu ý rằng đầu ra của lệnh sed được dẫn qua 'bash' để thực thi nó. Để lần đầu tiên nhìn thấy tệp di chuyển được đề xuất mà KHÔNG thực sự di chuyển chúng, trước tiên hãy xóa '| bash 'ở cuối, và thử nó như vậy:

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'

Điều này sẽ không thực hiện bất kỳ thay đổi nào, nhưng bạn sẽ thấy lệnh sẽ được thực thi NẾU bạn chạy nó với '| bash 'được gắn thẻ ở cuối.

Điều này rất hữu ích vì bạn có thể tạo bất kỳ thư mục con nào bạn muốn từ các phần trong tên tệp hoặc bất kỳ thứ gì khác mà bạn thêm vào văn bản 'thay thế' trong lệnh sed. Lưu ý rằng sed đòi hỏi rất nhiều nhân vật thoát, mặc dù.

SED Regex ngoặc:

(...) Yêu cầu thoát để nhóm chụp -> \ (... \)

{m, n} yêu cầu thoát để định lượng đối tượng trước -> \ {m, n \}

/ yêu cầu thoát trong chuỗi thay thế -> \ /

[...] KHÔNG yêu cầu thoát cho các lớp nhân vật

\ 1 trong chuỗi thay thế đề cập đến nhóm bị bắt đầu tiên, v.v.

CẢNH BÁO BẢO MẬT: KHÔNG BAO GIỜ ĐƯA RA BẤT CỨ VIỆC 'bash' KHÔNG GIỚI HẠN BẠN HOÀN TOÀN HIỂU R OUT RÀNG ...

Hy vọng rằng sẽ giúp xóa một số tắc nghẽn :)


1

Cài đặt mmv, sau đó làm điều này:

mmv "*.sql" "#1.php"
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.