여러 파일의 확장자를 어떻게 바꾸나요?


479

디렉토리에는 많은 *.html파일 이 있습니다. 모두 이름을 바꾸고 싶습니다*.txt

어떻게해야합니까? bash 쉘을 사용합니다.

답변:


382

더 나은 솔루션 (외부 호출이 아닌 bash 기능 만있는) 은 다른 답변 중 하나를 참조하십시오 .


다음은 시스템에 rename프로그램 이 있어야 할 필요가 없으며 시스템에서 가장 자주 프로그램 을 갖 더라도 필요합니다 .

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

편집 : 주석에서 지적했듯이 적절한 인용 부호가없는 파일 이름에는 공백이 없습니다 (이제 위에서 추가). 파일 이름에 공백이 없다는 것을 알고있는 파일에서 순수하게 작업 할 때 이것이 작동하지만 나중에 재사용 할 수있는 것을 쓸 때마다 적절한 인용을 건너 뛰지 마십시오.


47
mv "$ {file}" "$ {file / %. html / .txt}"(예 : man bash, 매개 변수 확장 참조)
Rodrigo Queiro

7
물론 기본 이름이 경로 이름 부분을 제거하기 때문에 파일이 모두 현재 디렉토리에있는 경우에만 좋습니다. 그냥 '주의'!
Jonathan Leffler

6
이 솔루션은 속도가 느릴뿐 아니라 파일 이름에 공백이 포함되어 있지 않기 때문에 좋지 않습니다. 항상 bash 스크립트에서 적절한 인용을해야합니다. mv "$ file" "$ (기본 이름"$ file ".html)". txt가 훨씬 좋습니다. 그러나 여전히 mv "$ files" "$ {files % .html} .txt"가 훨씬 좋습니다.
Balázs Pozsár

8
창문에서 당신은 방금ren *.a *.b
Muhammad Umer

2
최소한 $()레거시 백틱 구문 대신 POSIX 지정을 사용하십시오. 가독성을 향상시키고 백 슬래시로 이스케이프 처리해야하는 문자를 후자로 대체하여 문자로 대체하면 구문이 훨씬 모호해집니다.
Charles Duffy

668

bash를 사용하는 경우 sed, basename, rename, expr 등과 같은 외부 명령이 필요하지 않습니다.

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

12
파일 확장자를 모르는 경우 사용할 수 "${file%.*}.txt"있지만 확장자가없는 파일의 경우 에는 위험 할 수 있습니다.
Jess

1
내가했던 것처럼이 작업을 수행하는 데 문제가있는 사람에게주의하십시오 : $중괄호 안에는 없습니다 !
doug65536

5
이 답변을 영구적으로 즐겨 찾기 / 북마크 할 수있는 방법이 필요합니다. 정확한 구문을 기억하지 못하고 결국 인터넷 검색을합니다.
boliva

7
@danip 대괄호 안에 퍼센트 기호는 문자를 끝에서 제거합니다. 처음부터 문자를 제거하는 대괄호 안에 해시 구문도 있습니다. 그것을 확인하십시오 : tldp.org/LDP/abs/html/parameter-substitution.html#PSUB2

4
다른 스택 교환 답변 (찾을 수 없음!)은 이것을 제안했지만 --"operator"를 사용합니다 . mv- "$ file" "$ {file % .html} .txt"이 연산자는 파일 이름으로 시작하는 것을 방지합니다 mv가 인수로 파싱하는 '-'
rcreswick

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

정확히 당신이 원하는 것을합니다.


나는 당신이 제안한 것처럼 bash에서 리터럴 정규 표현식을 사용할 수 있다고 생각하지 않는다-어떤 쉘을 사용하고 있습니까?
DaveR

1
나는 맥 터미널을 사용하고 있습니다
bmw0128

Ubuntu의 이름 바꾸기 버전에 대한 매뉴얼 페이지는 다음과 같습니다. unixhelp.ed.ac.uk/CGI/man-cgi?rename
Amber

rename은 일부 시스템에서 명령입니다. 나는 일을하는 Perl 스크립트 (원래 첫 번째 낙타 책에서)를 가지고 있습니다. 거의 동일한 작업을 수행하는 동일한 이름의 GNU 프로그램도 있습니다. 내 Mac에는 시스템에서 제공 한 '이름 바꾸기'명령이 없거나 PATH에 있지 않습니다 (보통 포괄적 임).
Jonathan Leffler

Homebrew에는 이름 바꾸기 수식이 있습니다.
revprez

112

이것은 OSX에서 .txt에서 .txt_bak까지 나를 위해 일했습니다.

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

4
리눅스에서도 잘 작동합니다.
Diziet

이 점 외에,하지만에서 이동 .txt.txt_bak그냥 연결하는이 _bak)
corwin.amber

3
이것은 재귀 적으로 이름을 바꾸는 데 좋습니다
leachryanb

큰! (우분투 16.04 하에서) 나의 실제 사용 사례, 모든 위치 .scss에서 .sass(현재 위치 변환 후…)로 이름 바꾸기 :find . -name '*.scss' -exec sh -c 'mv "$0" "${0%.scss}.sass"' {} \;
Frank Nocke

2
이 6000 개 파일과 협력, 이름 바꾸기는 "인수 목록이었다 너무 오래"보고
토니 크로닌을

94

사용하고 싶습니다 rename:

rename -S .html .txt *.html

이것은 원하는 것을 정확히 수행합니다- 일치하는 모든 파일 의 확장자를에서 .html로 변경합니다 ..txt*.html

참고 : Greg Hewgill은 이것이 bash 내장이 아니라고 정확하게 지적합니다. 별도의 Linux 명령입니다. 만약 당신이 리눅스에서 무언가를 원한다면 이것은 잘 동작 할 것이다; 더 크로스 플랫폼이 필요한 경우 다른 답변 중 하나를 살펴보십시오.


7
이것은 좋은 솔루션이지만 rename프로그램이 관련이 없으며 bash모든 플랫폼에서 사용 가능한 것은 아닙니다. 나는 리눅스에서만 그것을 보았다.
Greg Hewgill

15
"$ rename .html .txt * .html"은 "(eval 1) 1 행,". "근처의 구문 오류입니다.
Amber

8
올바른 구문은 rename -S .html .text *.html다음을 -S의미합니다--subst-all
Marek Sebera

8
brew 설치 이름 바꾸기
Nick

4
@GregHewgill 이름 바꾸기는 사제와 맥 OS 사용할 수 있습니다
CodeBrauer


15

우분투 사용자의 경우 :

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

이것은 재귀 적이 지 않지만 우분투 14.04에서 나를 위해 일했습니다.
Max Wallace

9

이것은 내가 찾은 가장 매끄러운 솔루션으로 OSX 및 Linux에서 작동하며 git에서도 잘 작동합니다!

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

그리고 자식으로 :

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


8

다음은 rename 명령의 예입니다.

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

-n은 테스트 실행이며 실제로 파일을 변경하지 않음을 의미합니다. -n을 제거하면 이름이 바뀔 파일 목록이 표시됩니다. 위의 경우 현재 디렉토리의 모든 파일을 파일 확장자가 .htm에서 .html로 변환합니다.

위의 테스트 실행 결과가 정상으로 보이면 최종 버전을 실행할 수 있습니다.

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

-v는 선택 사항이지만 아래 샘플 출력에 표시된 것처럼 rename 명령으로 변경 한 유일한 레코드이므로 포함시키는 것이 좋습니다.

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

중간에 까다로운 부분은 정규식으로 Perl을 대체 한 것으로 아래에 강조 표시되어 있습니다.

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

6

이 질문에는 Bash가 명시 적으로 언급되어 있지만 ZSH를 사용할 수 있으면 매우 간단합니다.

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

당신이 얻는 zsh: command not found: zmv다면 간단하게 실행하십시오 :

autoload -U zmv

그런 다음 다시 시도하십시오.

zmv에 대한 팁에 대한 이 원본 기사 덕분에 .


4

다른 사람의 웹 사이트가 크롤링 된 후, 광범위한 하위 디렉토리에서 .html 확장자가없는 수천 개의 파일이 생겼습니다.

이미 .html 확장자를 가진 파일을 제외하고 한 번에 모두 이름을 바꾸려면 (대부분은 전혀 없었습니다), 이것은 나를 위해 일했습니다.

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

OP의 경우 * .txt 파일의 이름 만 바꾸도록 약간 수정할 수 있습니다.

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

세분화 (해머 타임!) :

-iname * .txt-
이미 .txt로 끝나는 파일 만 고려함

mv -iv "{}. {txt, html}"- find 가 {}을 파일 이름으로 {}를 전달하면 $ {filename %. *}은 확장자없이 기본 이름을 추출하여 매개 변수를 mv로 구성 합니다. bash 는 {txt, html}을 사용하여 두 개의 매개 변수로 다시 작성하므로 최종 명령은 다음과 같이 실행됩니다.mv -iv "filename.txt" "filename.html"

그래도 필요한 수정 : 파일 이름에서 공백 처리


4

명령mmv 은 엄청난 수의 파일 (초당 수만)에서이 작업을 매우 효율적으로 수행하는 것 같습니다. 예를 들어, 모든 .xml파일의 이름 을 .html파일 로 바꾸려면 다음을 사용하십시오.

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

(가) ;경로와 일치 것이라고는 *파일 이름과 일치합니다, 이들은라고도 #1하고 #2대체 이름.

기반 exec또는 파이프 에 대한 응답 이 너무 많은 파일에서 너무 느리거나 실패했습니다.



3

파티에 조금 늦었 어 xargs로 할 수 있습니다 :

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

또는 모든 파일이 일부 폴더에있는 경우

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

3
아니요 . 파싱하지 마십시오ls . 이 명령은 말도 ls안됩니다. 글로브를 직접 사용하는 대신 쓸데없이 글로브를 사용합니다. 공백, 따옴표 및 따옴표가 없기 때문에 glob 문자가 포함 된 파일 이름으로 중단됩니다.
gniourf_gniourf

참고로, 귀하의 링크 된 기사에는 최신 LS가 '터미널로 인쇄 된 경우 파일이 "쉘 이스케이프"되어 있음을 나타내는 업데이트 된 메모가 포함되어 있습니다. 그래도 요점은 여전히 ​​좋은 경험입니다.
Katastic Voyage

3

여러 확장을 한 번에 수정하는 좋은 방법입니다.

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

참고 : 확장 크기가 같아야합니다 (???).


2

좋고 간단합니다!

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

2

: 당신이 PERL을 선호하는 경우, 정확하게 당신이 여기에 원하는 것을 할 것입니다 (원래 래리 벽, PERL의 창조자에 의해 작성) 짧은 PERL 스크립트가 tips.webdesign10.com/files/rename.pl.txt은 .

귀하의 예를 들어 다음과 같은 트릭을 수행해야합니다.

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

2
이 질문은 이미 오래 전에 받아 들여져 왔으며, 당신의 대답이 이미 말한 것보다 더 많은 것을 가져 오는 것 같지는 않습니다.
ChristopheLec

1
Larry Wall 스크립트 (Robin Barker가 수정)이므로 +1입니다. 사용 가능한 마지막 URL은 tips.webdesign10.com/files/rename.pl.txt
loretoparisi

1

이전에 제안 된 것과 마찬가지로 이것이 내가 한 일입니다.

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

나는 처음으로 검증했다

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

1

한 줄, 루프 없음 :

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

예:

$ 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

기존 확장명을 정확히 일치시키는 데 의존하지 않는 bash 전용 방법을 보여주기 위해 +1. 이것은 3 자 길이 또는 4 자 길이 이상이든 모든 입력 확장에 적용됩니다
Ciprian Tomoiagă

0

불행히도 휴대하기 쉬운 것은 아닙니다. 아마도 약간의 expr 마술이 필요할 것입니다.

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

원하는대로 수행하면 반향을 제거하십시오.

편집 : basename 이 경우에는 좀 더 읽기 쉽지만 expr일반적으로 더 유연합니다.


이것이 질문에 대한 최선의 답변이 아닐 수도 있지만, 그것은 나에게 적합했습니다! 파일 이름뿐만 아니라 전체 경로에서만 문자열로 이름을 바꿀 수있는 방법이 필요했습니다. 게시 해 주셔서 감사합니다!
도넛

0

여기에 .edge파일 이름을 바꾸는 데 사용한 것이 있습니다..blade.php

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

매력처럼 작동합니다.



0

다른 패키지없이 현재 디렉토리 및 하위 디렉토리에있는 모든 파일의 파일 확장자 이름을 바꿉니다 (쉘 스크립트 만 사용).

  1. rename.sh다음 코드를 사용하여 현재 디렉토리 아래 에 쉘 스크립트를 작성하십시오 .

    #!/bin/bash
    
    for file in $(find . -name "*$1"); do
      mv "$file" "${file%$1}$2"
    done
  2. 에 의해 실행하십시오 ./rename.sh .old .new.

    예 : ./rename.sh .html .txt

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.