Đổi tên đệ quy các tệp (mở rộng thay đổi) trong Linux


22

Làm cách nào để đổi tên tất cả các tệp trong một thư mục, theo cách đệ quy, thay đổi một phần mở rộng tệp này sang một tệp khác, cho hàng ngàn tệp trong hàng ngàn thư mục con? Tôi thấy rất nhiều lệnh làm gần như những gì tôi muốn, nhưng không hoàn toàn.

find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."

...

rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile

1
Bạn có Debian renamehay Red Hat renamekhông?
Ignacio Vazquez-Abrams

@Ignacio: Ubuntu = Debian?
endolith

Vâng, Ubuntu là một dẫn xuất Debian.
Ignacio Vazquez-Abrams

Câu trả lời:


23

Tìm ra

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile

tất nhiên loại bỏ -v khi thực sự làm điều đó, hoặc nó sẽ lãng phí thời gian hiển thị tất cả các tệp


14

Cái gì đó như:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

cái này hoạt động tốt nhất với tôi
cwd


4

Tôi thấy phương pháp này dễ đọc và dễ đọc hơn:

find . -name "*.andnav" | rename "s/\.andnav$/.tile/"

Ít nhất trên các dẫn xuất Ubuntu, việc đổi tên lấy danh sách các tệp từ STDIN nếu không có tệp nào trên dòng lệnh. Và điều này có thể được kiểm tra dễ dàng với:

find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/"

cho đến khi bạn làm đúng


1

Đổi tên tập tin và thư mục với find -execdir | rename

Nếu bạn định đổi tên cả tệp và thư mục không chỉ đơn giản bằng hậu tố, thì đây là một mẫu tốt:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find . -depth -execdir rename 's/findme/replaceme/' '{}' \;

-execdirTùy chọn tuyệt vời thực hiện một cdvào thư mục trước khi thực hiện renamelệnh, không giống như -exec.

-depth đảm bảo rằng việc đổi tên xảy ra trước tiên đối với trẻ em và sau đó là cha mẹ để ngăn ngừa các vấn đề tiềm ẩn với các thư mục cha mẹ bị thiếu.

-execdir là bắt buộc vì đổi tên không chơi tốt với các đường dẫn đầu vào không phải là tên cơ sở, ví dụ như các lỗi sau:

rename 's/findme/replaceme/g' acc/acc

Việc PATHhack là bắt buộc vì -execdircó một nhược điểm rất khó chịu: findcực kỳ quan tâm và từ chối làm bất cứ điều gì -execdirnếu bạn có bất kỳ đường dẫn tương đối nào trong PATHbiến môi trường của mình , ví dụ: ./node_modules/.binthất bại với:

find: Đường dẫn tương đối './node_modules/.bin' được bao gồm trong biến môi trường PATH, không an toàn khi kết hợp với hành động -execdir của find. Vui lòng xóa mục nhập đó khỏi $ PATH

Xem thêm: https://askubfox.com/questions/621132/why-USE-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdirlà một phần mở rộng tìm GNU cho POSIX . renamelà dựa trên Perl và đến từ renamegói. Đã thử nghiệm trong Ubuntu 18.10.

Đổi tên cách nhìn

Nếu đường dẫn đầu vào của bạn không xuất phát findhoặc nếu bạn đã có đủ sự khó chịu của đường dẫn tương đối, chúng ta có thể sử dụng một số giao diện Perl để đổi tên thư mục một cách an toàn như trong:

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

Tôi đã không tìm thấy một chất tương tự thuận tiện cho việc -execdirvới xargs: xargs: thay đổi thư mục làm việc để đường dẫn tập tin trước khi thực hiện?

Các sort -ryêu cầu để đảm bảo rằng các tập tin đến sau khi các thư mục tương ứng của họ, kể từ khi con đường còn đi sau những ngắn hơn với tiền tố giống nhau.

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.