Làm cách nào để đổi tên nhiều tệp bằng cách thay thế chuỗi trong tên tệp? chuỗi này chứa một # #


42

https://serverfault.com/questions/70939/how-to-replace-a-text-opes-in-mult Môn-files-in-linux

https://serverfault.com/questions/228733/how-to-rename-multipl-files-by-replaces-word-in-file-name

https://serverfault.com/questions/212153/replace-opes-in-files-with-certain-file-extension

https://serverfault.com/questions/33158/searching-a-number-of-files-for-a-opes-in-linux

Những bài viết được đề cập đã trả lời tất cả câu hỏi của tôi. Tuy nhiên không ai trong số họ làm việc cho tôi. Tôi nghi ngờ đó là bởi vì chuỗi tôi đang cố gắng thay thế có # trong đó. Có một cách đặc biệt để giải quyết điều này?

Tôi có tệp hình ảnh đã thay thế bằng # U00a9 trong quá trình di chuyển trang web. Chúng trông như thế này:

Lucky-#U00a9NBC-80x60.jpg
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
Lucky-#U00a9NBC-250x250.jpg
Lucky-#U00a9NBC-282x232.jpg
Lucky-#U00a9NBC-300x150.jpg
Lucky-#U00a9NBC-300x200.jpg
Lucky-#U00a9NBC-300x250.jpg
Lucky-#U00a9NBC-360x240.jpg
Lucky-#U00a9NBC-400x250.jpg
Lucky-#U00a9NBC-430x270.jpg
Lucky-#U00a9NBC-480x240.jpg
Lucky-#U00a9NBC-600x240.jpg
Lucky-#U00a9NBC-600x250.jpg
Lucky-#U00a9NBC.jpg

và tôi muốn thay đổi nó thành một cái gì đó như thế này:

Lucky-safeNBC-80x60.jpg
Lucky-safeNBC-125x125.jpg
Lucky-safeNBC-150x150.jpg
Lucky-safeNBC-250x250.jpg
Lucky-safeNBC-282x232.jpg
Lucky-safeNBC-300x150.jpg
Lucky-safeNBC-300x200.jpg
Lucky-safeNBC-300x250.jpg
Lucky-safeNBC-360x240.jpg
Lucky-safeNBC-400x250.jpg
Lucky-safeNBC-430x270.jpg
Lucky-safeNBC-480x240.jpg
Lucky-safeNBC-600x240.jpg
Lucky-safeNBC-600x250.jpg
Lucky-safeNBC.jpg

CẬP NHẬT:

Tất cả các ví dụ này đều bắt đầu bằng "LU00a9ucky nhưng đây là nhiều hình ảnh với các tên khác nhau. Tôi chỉ đơn giản là nhắm mục tiêu vào phần" # U00a9 "của chuỗi để thay thế bằng" an toàn ".


3
Vì vậy, những gì bạn đã thực sự cố gắng? Tôi thấy rằng bạn đã liên kết với một vài câu hỏi và nói rằng họ thất bại, nhưng họ đã thất bại như thế nào? IMO ví dụ tốt nhất sử dụng renamelệnh. Tôi nghi ngờ việc đổi tên của bạn sẽ đơn giản như rename -n 's/#/safeNBC/' *.jpg.
Zoredache

Tôi đã thử rename -n 's/#U00a9/safe/' *.jpgvà lệnh được chấp nhận nhưng không có thay đổi nào xảy ra.

Chắc chắn, như bạn đã thấy từ các tài liệu bạn chắc chắn đã xem xét, đó -nno acttùy chọn. Cho phép bạn xem nếu nó hoạt động trước khi bạn thực sự sử dụng nó. Đầu ra trên màn hình có hiển thị đúng tên mới không?
Zoredache

Tôi xin lỗi tôi đã sao chép và dán ví dụ của bạn mà không chú ý đầy đủ, tôi đã thực hiện lệnh đổi tên mà không có -n. Tôi tin rằng @DTK giải quyết vấn đề, tôi đã không thoát khỏi #.

Thay thế các chuỗi trong tên tệp trên MacOS: superuser.com/questions/152627/ triệt
Anton Tarasenko

Câu trả lời:


64

Để thay thế #bằng somethingelsetên tệp trong thư mục hiện tại (không phải đệ quy), bạn có thể sử dụng tiện ích đổi tên GNU :

rename  's/#/somethingelse/' *

Nhân vật như -phải được thoát với a \.

Đối với trường hợp của bạn, bạn sẽ muốn sử dụng

rename 's/#U00a9/safe/g' *

Lưu ý rằng nếu bạn chỉ muốn thao tác trên một lựa chọn tệp nhất định, ví dụ: chỉ *.jpg, điều chỉnh đầu vào cuối cùng để khớp với lựa chọn đó:

rename 's/#U00a9/safe/g' *.jpg

Để thực hiện kiểm tra trước khi thực sự thay đổi tên tệp, hãy sử dụng -ncờ:

demo/> ls                               
Lucky-#U00a9NBC-125x125.jpg  
Lucky-#U00a9NBC-150x150.jpg 

demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)

Đối với OS X, đổi tên GNU có thể được cài đặt bằng homebrew : brew install rename.


Điều này không hoạt động trên máy của tôi (Arch Linux), nhưng câu trả lời của mik đã làm.
marcvangend

@marcvangend Phiên bản nào renamebạn đang sử dụng? # sudo pacman -S perl-renamesẽ cài đặt phiên bản perl, phiên bản mạnh hơn và có thể đủ để làm cho câu trả lời này phù hợp với bạn.
John Gowers

@JohnGowers Cảm ơn! Tôi đã không nhận ra có hai phiên bản. Trên hệ thống của tôi, rename --versiontrả về rename from util-linux 2.29.2vì vậy đó thực sự không phải là phiên bản perl.
marcvangend

5
Có hai renametiện ích chung nhưng cả hai đều không được GNU phát triển: Các bản phân phối dựa trên Debian bao gồm một renametiện ích với gói Perl của chúng trong khi các bản phân phối dựa trên Red Hat sử dụng renametiện ích từ util-linuxTổ chức hạt nhân Linux. Liên kết của bạn là đến hàmrename C từ thư viện chuẩn GNU.
Anthony G - công lý cho Monica

2
Trong câu trả lời này, tại sao chúng ta phải viết /gvàorename 's/#U00a9/safe/g' *
Nikhil

21

tìm danh sách các tập tin và sau đó thay thế từ khóa. dưới đây là ví dụ

find . -name '*jpg' -exec bash -c ' mv $0 ${0/\#U00a9NBC/safeNBC}' {} \;

1
Bạn cần một số trích dẫn kép xung quanh các mvđối số của mình , trong trường hợp có khoảng trắng trong tên
Ngừng làm hại Monica

Tôi cần phải thay thế tất cả các tệp * _spec.rb thành * _controll_spec.rb và giải pháp của bạn đã làm việc cho tôi. Thanx.
jedi

18

Điều này không khó, chỉ cần đảm bảo thoát khỏi octothorpe (#) trong tên bằng cách thêm dấu gạch chéo ngược (\).

find . -type f -name 'Lucky-*' | while read FILE ; do
    newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
    mv "${FILE}" "${newfile}" ;
done 

Lời giải thích của bạn có ý nghĩa, thoát khỏi những #âm thanh như những gì tôi cần. Tôi không thấy dấu gạch chéo ngược trong ví dụ của bạn. Nó sẽ trông như thế này: s/\#U00a9/safe/

@LeonFrancisShelhamer bắt tốt. Nó nuốt chửng dấu gạch chéo ngược. Tôi sẽ sửa đổi.

17

Để thoát khỏi #shell, chỉ cần sử dụng dấu ngoặc đơn ( '#'), dấu ngoặc kép ( "#") hoặc dấu gạch chéo ngược ( \#).

Đơn giản nhất trong trường hợp của bạn là sử dụng renamelệnh (nếu có):

rename '#U00a9' safe *.jpg

2
Cảm ơn. Mặc dù câu trả lời được bình chọn cao nhất ( rename 's/#/somethingelse/' *) không hoạt động trên máy của tôi (Arch Linux), nhưng câu trả lời này đã làm.
marcvangend

1
Điều này hoạt động bằng cách sử dụng lệnh đổi tên từ produc-linux.
imclean

10

không chắc chắn làm thế nào để trong sed, nhưng bạn có thể thử điều này trong một bash shell:

for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;

giải trình:

  1. các vòng lặp thông qua tất cả các tên tệp khớp với toàn cầu (Lucky- # U00a9NBC - *. jpg)
  2. đổi tên tập tin bằng lệnh di chuyển (mv)
  3. sử dụng thay thế tham số bash gốc $ {var / Pattern / Alternative} để tạo tên mới ("$ {f / # U00a9 / safe}")

Thông tin thêm về thay thế tham số (IMO được sử dụng không đúng mức): http://www.tldp.org/LDP/abs/html/parameter-substlation.html


Mặc dù mã này có thể trả lời câu hỏi, nhưng nó không hữu ích lắm. Giải thích cách giải quyết vấn đề sẽ cải thiện tính hữu ích và giá trị lâu dài của câu trả lời.
Anthony G - công lý cho Monica

thêm lời giải thích hướng dẫn và đọc thêm theo nhận xét của Anthony.
Gregory Patmore

1

Các ví dụ trên không hoạt động trên hệ thống của tôi (CentOS 5.6) vì vậy tôi đã tìm thấy một lệnh (có thể cụ thể hơn cho hệ thống) hoạt động (lưu ý: cần phải thoát '#' bằng \dòng lệnh):

rename \#U00a9 safe *.jpg

[Ngoài ra: Tôi không có đủ uy tín chưa bình luận, vì vậy để đáp lại câu hỏi của Nikhil về việc sử dụng /gtrong rename 's/old_string/new_string/g'(đặt ra trong các ý kiến cho một câu trả lời ở trên):

Sử dụng công cụ gsửa đổi để thực hiện thay thế 'toàn cầu' (nghĩa là thay thế new_ chuỗi cho old_ chuỗi nhiều lần khi old_ chuỗi xảy ra). Điều này không cần thiết trong câu trả lời của tôi bởi vì renamenó sẽ được áp dụng cho tất cả các tệp được chỉ định với *. Xem https://www.computerhope.com/unix/rename.htm để được giải thích ngắn gọn về điều này và các sửa đổi khác.]


Chính xác; Các hệ điều hành có nguồn gốc từ Fedora như CentOS có phiên bản khác renamevới các hệ điều hành có nguồn gốc từ Debian. Xem unix.stackexchange.com/a/238862/135943 . Và nhân tiện, CentOS 5.6 khá cũ và tôi khuyên bạn nên nâng cấp.
tự đại diện

Ah, cảm ơn đã giải thích + liên kết. Hệ điều hành lỗi thời đang hoạt động và do đó tôi không thể nâng cấp :) nhưng một cụm mới đang được xây dựng và có lẽ chúng tôi sẽ nâng cấp khi chúng tôi chuyển qua ...
Ezra Citron

0

Đây là giải pháp của DTK được gói trong chức năng bash có thể tái sử dụng:

function renameFilesRecursively () {

  SEARCH_PATH="$1"
  SEARCH="$2"
  REPLACE="$3"

  find ${SEARCH_PATH} -type f -name "*${SEARCH}*" | while read FILENAME ; do
      NEW_FILENAME="$(echo ${FILENAME} | sed -e "s/${SEARCH}/${REPLACE}/g")";
      mv "${FILENAME}" "${NEW_FILENAME}";
  done

}

Đây là cách bạn có thể sử dụng nó:

renameFilesRecursively /home/user/my-files apple orange

0

Trên thực tế renamecó một tùy chọn chính xác cho cái gọi là --substhoặc -strong ngắn hạn. Không cần sử dụng cú pháp regex.

rename -s '#U00a9' 'safe' *

Nếu bạn muốn thay thế / thay thế nhiều lần, sử dụng --subst-allhoặc -S.

BTW, tôi chỉ muốn thay thế một chuỗi bằng không có gì (xóa nó khỏi tên tệp) ... chúng tôi cũng có một tùy chọn cho nó -d/--delete-D/--delete-all:

rename -d '#U00a9' *

-1

Một tùy chọn khác là sử dụng pyRenamer, một ứng dụng được tạo riêng cho việc đổi tên hàng loạt.

Nó có thể được cài đặt với sudo apt-get install pyrenamer

Để biết chi tiết sử dụng, hãy tham khảo tệp README của nó trên GitHub .


1
Nếu bạn thực sự nghĩ rằng điều này có thể trả lời câu hỏi xin vui lòng thêm một số lời giải thích cho câu trả lời của bạn. Bản thân nó, nó chỉ cài đặt một gói. Bạn nên giải thích những gì lệnh làm và cung cấp một ví dụ xử lý yêu cầu cụ thể của OP.
roaima
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.