이름의 일부를 제거하려면 정규식을 사용하여 파일 이름을 바꿉니다.

이름의 일부를 제거하려면 정규식을 사용하여 파일 이름을 바꿉니다.

Linux 시스템에서 처리해야 하는 파일이 많이 있습니다. 파일은 다음과 같습니다.

2009-08-18T034353_DR1_4N-NAC_123456_1234_band1.ntf          
2009-08-18T034353_DR1_4N-NAC_123456_1234_browse.jpg    
2009-08-18T034353_DR1_4N-NAC_123456_1234_band2.ntf    
2009-08-18T034353_DR1_4N-NAC_123456_1234_license.txt    
2009-08-18T034353_DR1_4N-NAC_123456_1234_metadata.xml     
2009-08-18T034353_DR1_4N-NAC_123456_1234_readme.txt      
2009-08-18T034353_DR1_4N-NAC_123456_1234_udm.tif

이 부분을 제거하고 싶습니다. -NAC_123456_1234첫 번째 부분은 영숫자로 구성될 수 있고 숫자 부분은 숫자로만 구성될 수 있습니다.

이름 바꾸기 명령을 시도했지만 작동하지 못했습니다. 나는 다음과 같은 것을 생각했습니다.

rename '/-[a-zA-Z]+_[0-9]+_[0-9]+//' *.*

내가 무엇을 놓치고 있는지 알아내도록 도와줄 수 있는 사람이 있나요?

내 이름이 바뀐 버전은 다음과 같습니다.

rename from util-linux 2.23.2

답변1

사용하려는 구문은 Perl rename명령용입니다. 운영 체제에 따라 이 옵션을 prename또는 로 사용하거나 설치할 수 있지만 perl-rename이 옵션이 필요하며아니요from은 시도 중인 정규식 구문을 rename사용합니다 . util-linux그리고 이것에도 불구하고 약간 다른 것이 필요합니다.

perl-rename 's/-[a-zA-Z]+_[0-9]+_[0-9]+//' *.*

실제로 원하는 것은 마지막 항목 이후의 모든 항목을 삭제하는 것이므로 다음을 -사용할 수 있습니다.

perl-rename 's/(.*)-(.*)(\.*)/$1$2/' *.*

하지만 이 도구를 사용할 필요는 없습니다. 작은 쉘 루프를 실행할 수 있습니다.

for file in *; do
    ext="${file##*.}"
    newName="${file%-*}.$ext"
    echo mv -- "$file" "$newName"
done

이는 실행될 명령만 인쇄합니다. 만족스러우면 정확하다면 삭제 echo하고 다시 실행하여 실제로 이름을 바꾸세요.

설명하다

  • for file in *: 현재 디렉터리의 모든 파일(및 디렉터리)을 반복하여 각 파일을 $file.
  • ext="${file##*.}": 구문은 ${variable##pattern}시작 부분에서 가장 긴 일치 항목을 제거합니다. 따라서 여기에서는 파일 확장자를 남기고 마지막 파일까지 모든 것을 제거합니다.pattern$variable.
  • newName="${file%-*}.$ext"${variable%pattern}: 구문이 의 끝에서 제거하는 가장 짧은 일치 항목입니다. 그래서 여기서는 끝까지 모든 것을 우리에게 맡길 것입니다. 그런 다음 확장자를 추가하여 새 파일 이름을 지정합니다.pattern$variable-
  • mv -- "$file" "$newName": 파일 이름을 바꿉니다.

답변2

가 있는 경우 zsh거기에서 수행하는 것이 더 쉽고 안전하며 이식성이 뛰어납니다.

autoload -Uz zmv
zmv -n '(*-)[[:alnum:]]##_<->_<->(*.*)' '$1$2'

( -n만족할 경우 제거(모의 실행)).

이는 extendedglob정규식 대신 쉘 글로브(zsh 지원)를 사용하지만 기능 측면에서는 확장 정규식과 동일합니다.

  • *일반적으로 임의 개수의 문자(또는 유효한 문자를 형성하지 않는 바이트가 있는 경우 바이트)와 일치합니다. 이것이 (대부분의) 정규 표현식보다 안전한 이유 중 하나입니다.
  • [[:alnum:]]POSIX 문자 클래스에 대한 표준 일치입니다.
  • ##하나 이상의 이전 원자(예: +ERE/PCRE의 원자)입니다.
  • <->하나 이상의 ASCII 10진수로 구성된 임의의 시퀀스로 유사 <1-10>하지만 제한은 없습니다.

zmv이름 바꾸기를 시작하기 전에 일부 온전성 검사가 수행되어 rename주변의 다양한 변형보다 안전합니다.

관련 정보