Làm cách nào để đổi tên phần mở rộng cho một loạt các tệp?


480

Trong một thư mục, tôi có một loạt các *.htmltập tin. Tôi muốn đổi tên tất cả thành*.txt

Làm thế nào tôi có thể làm điều đó? Tôi sử dụng vỏ bash.

Câu trả lời:


382

Để có giải pháp tốt hơn (chỉ có chức năng bash, trái ngược với các cuộc gọi bên ngoài), hãy xem một trong những câu trả lời khác .


Những điều sau đây sẽ làm và không yêu cầu hệ thống phải có renamechương trình (mặc dù bạn thường xuyên có chương trình này trên hệ thống):

for file in *.html; do
    mv "$file" "$(basename "$file" .html).txt"
done

EDIT: Như đã chỉ ra trong các bình luận, điều này không hoạt động đối với tên tệp có khoảng trắng trong đó mà không có trích dẫn thích hợp (hiện đã được thêm ở trên). Khi làm việc hoàn toàn trên các tệp của riêng bạn mà bạn biết không có khoảng trắng trong tên tệp, điều này sẽ hoạt động nhưng bất cứ khi nào bạn viết một cái gì đó có thể được sử dụng lại sau đó, đừng bỏ qua trích dẫn thích hợp.


47
Một thay thế, không có tên cơ sở và có dấu ngoặc kép: mv "$ {file}" "$ {file /%. Html / .txt}" (xem man bash, Mở rộng tham số để biết chi tiết)
Rodrigo Queiro

7
Tất nhiên chỉ tốt nếu tất cả các tệp trong thư mục hiện tại, vì tên cơ sở loại bỏ phần tên đường dẫn. Chỉ là một 'cảnh giác'!
Jonathan Leffler

6
Giải pháp này rất tệ, không chỉ vì nó chậm mà còn không hoạt động với tên tệp có khoảng trắng trong đó. Bạn nên LUÔN LUÔN thực hiện trích dẫn thích hợp trong các tập lệnh bash. mv "$ file" "$ (tên cơ sở" $ file ".html)". txt sẽ tốt hơn nhiều. Tuy nhiên, mv "$ files" "$ {files% .html} .txt" tốt hơn nhiều.
Balázs Pozsár

8
trong cửa sổ bạn chỉ cần làmren *.a *.b
Muhammad Umer

2
Tối thiểu, sử dụng $()cú pháp POSIX được chỉ định thay vì cú pháp backtick cũ. Cải thiện khả năng đọc và làm cho cú pháp ít mơ hồ hơn khi bạn có các ký tự cần phải được gạch chéo ngược để thoát thành chữ bên trong thay thế lệnh bằng cái sau.
Charles Duffy

669

Nếu sử dụng bash, không cần các lệnh bên ngoài như sed, tên cơ sở, đổi tên, expr, v.v.

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done

12
Và nếu bạn không biết phần mở rộng tệp bạn có thể sử dụng "${file%.*}.txt", nhưng điều này có thể gây nguy hiểm cho các tệp không có phần mở rộng.
Jess

1
Lưu ý cho bất cứ ai gặp khó khăn khi làm việc này như tôi đã có: lưu ý rằng không có $bên trong niềng răng xoăn!
doug65536

5
Tôi cần một cách để yêu thích vĩnh viễn / đánh dấu câu trả lời này, tôi không bao giờ nhớ cú pháp chính xác và cuối cùng tôi đã googling cho nó
boliva

7
@danip Phần trăm ký hiệu trong khung xây dựng loại bỏ các ký tự ở cuối. Ngoài ra còn có một cấu trúc băm trong khung bóc tách các ký tự ra khỏi đầu. Kiểm tra xem: tldp.org/LDP/abs/html/parameter-substlation.html#PSUB2

4
Một câu trả lời trao đổi ngăn xếp khác (mà tôi không thể tìm thấy!) Đã đề xuất điều này, nhưng cũng sử dụng --"toán tử": mv - "$ file" "$ {file% .html} .txt" Toán tử đó ngăn tên tệp bắt đầu bằng a '-' khỏi bị phân tích cú pháp bởi mv làm đối số.
RCreswick

191
rename 's/\.html$/\.txt/' *.html

làm chính xác những gì bạn muốn.


Tôi không nghĩ bạn có thể sử dụng regex theo nghĩa đen trong bash như bạn đề xuất - bạn đang sử dụng shell nào?
DaveR

1
Tôi đang sử dụng thiết bị đầu cuối Mac
bmw0128

Đây là trang dành cho phiên bản đổi tên trên Ubuntu: unixhelp.ed.ac.uk/CGI/man-cgi?rename
Amber

đổi tên là một lệnh trên một số hệ thống. Tôi có một kịch bản Perl (ban đầu từ cuốn sách Camel đầu tiên) thực hiện công việc. Ngoài ra còn có một chương trình GNU cùng tên thực hiện cùng một công việc. Máy Mac của tôi không có lệnh 'đổi tên' do hệ thống cung cấp - hoặc nó không có trên PATH của tôi (có tính toàn diện vừa phải).
Jonathan Leffler

Có một công thức đổi tên trong Homebrew.
revprez

112

Điều này làm việc cho tôi trên OSX từ .txt đến .txt_bak

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

4
Hoạt động tốt trong linux.
Diziet 30/03/2015

Đó là bên cạnh những điểm, nhưng để đi từ .txtđể .txt_bakbạn chỉ phải tiếp nhau _bak;)
corwin.amber

3
Điều này là tốt để đổi tên đệ quy
leachryanb

Tuyệt quá! (trong Ubuntu 16.04) Trường hợp sử dụng thực tế của tôi, đổi tên tất cả .scssthành .sass(sau khi chuyển đổi tại chỗ):find . -name '*.scss' -exec sh -c 'mv "$0" "${0%.scss}.sass"' {} \;
Frank Nocke

2
điều này hoạt động với +6000 tệp, đổi tên báo cáo "danh sách đối số quá dài"
Tony Cronin

94

Bạn muốn sử dụng rename:

rename -S .html .txt *.html

Điều này thực hiện chính xác những gì bạn muốn - nó sẽ thay đổi phần mở rộng từ .htmlthành .txtcho tất cả các tệp phù hợp *.html.

Lưu ý: Greg Hewgill chỉ ra chính xác đây không phải là nội dung bash; và là một lệnh Linux riêng biệt. Nếu bạn chỉ cần một cái gì đó trên Linux thì nó sẽ hoạt động tốt; Nếu bạn cần một cái gì đó đa nền tảng hơn thì hãy xem một trong những câu trả lời khác.


7
Mặc dù đây là một giải pháp tốt, renamechương trình không liên quan bashvà cũng không có sẵn trên tất cả các nền tảng. Tôi chỉ thấy nó trên Linux.
Greg Hewgill

15
"$ đổi tên .html .txt * .html" dẫn đến ... lỗi cú pháp tại (eval 1) dòng 1, gần "."
Amber

8
Cú pháp đúng là rename -S .html .text *.htmlnơi -Sviết tắt của--subst-all
Marek Sebera

8
đổi tên cài đặt bia
Nick

4
@GregHewgill đổi tên có sẵn cho Mac OS với
HomeBrew


15

Đối với người dùng Ubuntu:

rename 's/\.html$/\.txt/' *.html

Điều này không đệ quy, nhưng nó hoạt động với tôi trên Ubuntu 14.04.
Max Wallace

9

Đây là giải pháp nhỏ nhất mà tôi thấy có hiệu quả trên OSX và Linux và nó cũng hoạt động tốt với git!

find . -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".tsx' - '{}' \;

và với git:

find . -name "*.js" -exec bash -c 'git mv "$1" "${1%.js}".tsx' - '{}' \;


8

Dưới đây là một ví dụ về lệnh đổi tên:

rename -n s/\.htm$/\.html/’ *.htm

-N có nghĩa là đó là bản chạy thử và sẽ không thực sự thay đổi bất kỳ tệp nào. Nó sẽ hiển thị cho bạn một danh sách các tệp sẽ được đổi tên nếu bạn xóa -n. Trong trường hợp trên, nó sẽ chuyển đổi tất cả các tệp trong thư mục hiện tại từ phần mở rộng tệp của .htm sang .html.

Nếu đầu ra của lần chạy thử trên có vẻ ổn thì bạn có thể chạy phiên bản cuối cùng:

rename -v s/\.htm$/\.html/’ *.htm

-V là tùy chọn, nhưng nên bao gồm nó vì đây là bản ghi duy nhất bạn sẽ có các thay đổi được thực hiện bằng lệnh đổi tên như được hiển thị trong đầu ra mẫu bên dưới:

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html

Phần khó ở giữa là phần thay thế Perl bằng các biểu thức chính quy, được tô sáng bên dưới:

rename -v s/\.htm$/\.html/’ *.htm

6

Câu hỏi này đề cập rõ ràng đến Bash, nhưng nếu bạn có sẵn ZSH thì nó khá đơn giản:

zmv '(*).*' '$1.txt'

Nếu bạn nhận được zsh: command not found: zmvthì chỉ cần chạy:

autoload -U zmv

Và sau đó thử lại.

Nhờ bài viết gốc này cho lời khuyên về zmv.


4

Sau khi thu thập dữ liệu trang web của người khác, tôi đã kết thúc với hàng ngàn tệp bị thiếu phần mở rộng .html, trên một cây thư mục con rộng.

Để đổi tên tất cả trong một lần, ngoại trừ các tệp đã có phần mở rộng .html (hầu hết trong số chúng không có gì cả), điều này hiệu quả với tôi:

cd wwwroot
find . -xtype f \! -iname *.html   -exec mv -iv "{}"  "{}.html"  \;  # batch rename files to append .html suffix IF MISSING

Trong trường hợp của OP, tôi có thể sửa đổi một chút, chỉ đổi tên các tệp * .txt, như vậy:

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 

Bị hỏng (hammertime!):

-iname * .txt
- Có nghĩa là xem xét các tệp CHỈ đã kết thúc bằng .txt

mv -iv "{}. {txt, html}" - Khi find vượt qua {} làm tên tệp, $ {filename%. *} trích xuất tên cơ sở của nó mà không có bất kỳ phần mở rộng nào để tạo tham số cho mv . bash lấy {txt, html} để viết lại thành hai tham số để lệnh cuối cùng chạy như sau:mv -iv "filename.txt" "filename.html"

Khắc phục sự cố cần thiết: xử lý khoảng trắng trong tên tệp


4

Các lệnhmmv dường như để làm nhiệm vụ này rất có hiệu quả trên một số lượng lớn các tập tin (hàng chục ngàn người trong một giây). Ví dụ: để đổi tên tất cả .xmlcác tệp thành .htmltệp, hãy sử dụng:

mmv ";*.xml" "#1#2.html"

những ;sẽ phù hợp với con đường, *sẽ phù hợp với tên tập tin, và chúng được gọi là #1#2trong tên thay thế.

Câu trả lời dựa trên exechoặc đường ống quá chậm hoặc thất bại trên một số lượng rất lớn các tệp.


3

Thử cái này

rename .html .txt *.html 

sử dụng:

rename [find] [replace_with] [criteria]

3

Một chút muộn để dự tiệc. Bạn có thể làm điều đó với xargs:

ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}

Hoặc nếu tất cả các tệp của bạn nằm trong một số thư mục

ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}

3
Số Đừng phân tích cú phápls . Lệnh này là vô lý: nó sử dụng một cách vô dụng với ls, thay vì sử dụng trực tiếp toàn cầu. Điều này sẽ phá vỡ với tên tệp chứa khoảng trắng, dấu ngoặc kép và (do thiếu dấu ngoặc kép) ký tự toàn cầu.
gniourf_gniourf

FYI, bài viết được liên kết của bạn chứa một ghi chú cập nhật cho biết các tệp "thoát vỏ" chính xác của LS mới hơn nếu được in ra thiết bị đầu cuối. ' Quan điểm của bạn vẫn là một quy tắc tốt của mặc dù.
Chuyến đi Katastic

3

Đây là một cách tốt để sửa đổi nhiều tiện ích mở rộng cùng một lúc:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

Lưu ý: hãy cẩn thận ở kích thước tiện ích mở rộng giống nhau (???)


2

Đẹp & đơn giản!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;

2

Nếu bạn thích PERL, có một đoạn script PERL ngắn (ban đầu được viết bởi Larry Wall, người tạo ra PERL) sẽ thực hiện chính xác những gì bạn muốn ở đây: tips.webdesign10.com/files/rename.pl.txt .

Ví dụ của bạn, sau đây nên thực hiện các mẹo:

rename.pl 's/html/txt/' *.html

2
Câu hỏi này đã được trả lời và chấp nhận từ lâu và dường như câu trả lời của bạn không mang lại điều gì nhiều hơn những gì đã được nói.
BarsheLec

1
+1 vì đó là kịch bản của Larry Wall (được sửa đổi bởi Robin Barker). Url có sẵn cuối cùng là đây: tips.webdesign10.com/files/rename.pl.txt
loretoparisi

1

Tương tự như những gì đã được đề xuất trước đây, đây là cách tôi đã làm:

find . -name '*OldText*' -exec sh -c 'mv "$0" "${0/OldText/NewText}"' {} \;

Lần đầu tiên tôi xác nhận

find . -name '*OldText*' -exec sh -c 'echo mv "$0" "${0/OldText/NewText}"' {} \;

1

Một dòng, không có vòng lặp:

ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}

Thí dụ:

$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt

+1 để hiển thị một cách chỉ bash không phụ thuộc vào việc khớp chính xác với tiện ích mở rộng hiện có. Điều này hoạt động cho bất kỳ tiện ích mở rộng đầu vào nào, có thể là 3 ký tự dài hoặc 4 ký tự dài trở lên
Ciprian Tomoiagă

0

Thật không may, nó không tầm thường để làm điều đó. Bạn có thể cần một chút phép thuật expr.

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

Loại bỏ tiếng vang một khi bạn hạnh phúc nó làm những gì bạn muốn.

Chỉnh sửa: basename có thể dễ đọc hơn một chút cho trường hợp cụ thể này, mặc dù exprnói chung là linh hoạt hơn.


Trong khi điều này có thể không phải là câu trả lời tốt nhất cho câu hỏi, nó là dành cho tôi! Tôi cần một cách để đổi tên chỉ trong chuỗi toàn bộ một đường dẫn, không chỉ là tên tệp. Cảm ơn vì đăng!
bánh rán

0

Đây là những gì tôi đã sử dụng để đổi tên .edgetập tin thành.blade.php

for file in *.edge; do     mv "$file" "$(basename "$file" .edge).blade.php"; done

Hoạt động như quyến rũ.


0

Bạn cũng có thể tạo một hàm trong Bash, thêm nó vào .bashrchoặc một cái gì đó và sau đó sử dụng nó bất cứ nơi nào bạn muốn.

change-ext() {
    for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}

Sử dụng:

change-ext css scss

Nguồn mã trong chức năng: https://stackoverflow.com/a/1224786/6732111


0

Đổi tên phần mở rộng tệp cho tất cả các tệp trong thư mục hiện tại và thư mục con mà không có gói nào khác (chỉ sử dụng tập lệnh shell):

  1. Tạo một tập lệnh shell rename.shtrong thư mục hiện tại với đoạn mã sau:

    #!/bin/bash
    
    for file in $(find . -name "*$1"); do
      mv "$file" "${file%$1}$2"
    done
  2. Chạy nó bằng cách ./rename.sh .old .new.

    Ví dụ. ./rename.sh .html .txt

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.