파일 이름에서 마지막에서 두 번째 확장자를 제거합니다.

파일 이름에서 마지막에서 두 번째 확장자를 제거합니다.

폴더에 잘못된 확장자를 가진 많은 파일이 포함되어 있다고 가정합니다.

Song1.avi.mp3
Song2.avi.mp3
Song32.web.mp3
Song23.mp4.mp3
Song2a.mp9.mp3

web두 번째 필드( , avi, ) 만 삭제하고 싶습니다 mp4. sed 사용법을 알고 있지만 확장 기능을 추가해야 합니다

 mv -v $i "$(echo $i|sed 's:.flv::g;s:.avi::g;s:.mp4::g')"

sed, awk 또는 perl을 사용하여 두 번째 잘못된 확장만 제거하는 간단한 방법을 아는 사람이 있습니까?

답변1

외부 유틸리티가 필요하지 않습니다.쉘 자체의 문자열 조작 기능. 이렇게 하면 특수 문자로 인해 파일 이름이 손상되는 것을 방지하는 것이 더 쉬워집니다. 그리고 기억해변수 대체에는 항상 큰따옴표를 사용하십시오..

mv -v -- "$i" "${i%.*.*}.${i##*.}"

(분명히 이 코드 조각은 파일 이름에 두 가지 확장자가 모두 포함되어 있다고 가정합니다. 그렇지 않은 경우 ${i%.*.*}전체 파일 이름입니다.)

답변2

Bash 정규 표현식을 사용하세요.

f=foo.bar.baz.qux
if [[ $f =~ (.+)\.[^.]+\.([^.]+)$ ]];then
    new="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
    if [[ -f "$new" ]]; then
        echo "moving $f would overwrite $new"
    else
        echo mv "$f" "$new"
    fi
fi
mv foo.bar.baz.qux foo.bar.qux

이것의 장점은 이름에 점이 2개 미만이면 아무 작업도 수행되지 않는다는 것입니다.

답변3

파일 이름이 일치하는지 확인해야 하고 따라서 실제로 수정하려는 두 확장명이 있는 파일의 이름만 바꾸려면 다음을 수행할 수 있습니다.

case ${i##*/} in (*.*.*)
mv -- "$i" "${i%.*.*}.${i##*.}"
;;esac

일치를 확인하지 않고 "$i"다음과 같은 glob으로 설정하는 경우를 이해하십시오.

for i in *
mv "$i" ...

...그런 다음 mv위와 동일한 명령을 사용합니다.(및 기타 답변)"$i.$i"패턴 불일치로 인해 파일이 var가 자체적으로 확장되는 위치로 이동될 수 있습니다.

답변4

다음 명령을 사용하여 쉽게 이름을 바꿀 수 있습니다 mmv.

$ mmv -n '*.*.*' '#1.#3'

또는 rename다음 명령을 사용하십시오.

$ rename -n 's:(.*)\..*(\..*):$1$2:' *

관련 정보