파일 이름 시작 부분에 동일한 단어가 포함되도록 수백 개의 파일 이름을 어떻게 바꿀 수 있습니까? [폐쇄]

파일 이름 시작 부분에 동일한 단어가 포함되도록 수백 개의 파일 이름을 어떻게 바꿀 수 있습니까? [폐쇄]

다음은 이름을 바꿔야 하는 파일의 작은 샘플입니다.

    ID_EDMSCP_20160815.txt.pgp
    ID_EDMSCP_20160816.txt.pgp
    ID_EDMSCP_20160817.txt.pgp
    ID_EDMSCP_20160818.txt.pgp       

다른 사람의 질문을 바탕으로 스크립트를 만들었는데 다음과 같습니다.

    for file in ID_EDMSCP_*.txt.pgp
    do
        mv -i "${file}" "${file/-ID-/-SUBMIT_GO_ID-}"
    done

그러나 다음 메시지가 나타납니다.

    mv: `ID_EDMSCP_20160815.txt.pgp' and `ID_EDMSCP_20160815.txt.pgp' are the same file

그리고 아무것도 이름이 바뀌지 않았습니다. 내가 뭐 놓친 거 없니?

답변1

mv -i "${file}" "${file/-ID-/-SUBMIT_GO_ID-}"

-ID-이 문자열 대체는 소스 파일 이름에 나타나지 않는 대체를 지시합니다 . 내 생각엔 당신이 이렇게 말하려는 것 같아요.

mv -i "${file}" "${file/ID_/SUBMIT_GO_ID_}"

또 다른 문제는 이것이 ksh93Bash와 Zsh에서도 사용할 수 있는 기능이라는 것입니다.순수 POSIX 쉘이 아님. #!/bin/sh스크립트 상단에서 사용 하면 POSIX 쉘 또는 POSIX 이전 Bourne 쉘 인터프리터에서 실행됩니다.일부 시스템에서는, 이것은 이해되지 않을 것입니다.

고급 셸의 비표준 기능에 액세스할 수 없는 경우 다양한 대안이 있습니다.

sed

이 스크립트를 모든 Unix 유형 시스템으로 이식해야 하는 경우 sed대체 스크립트로 전환할 수 있습니다.

mv -i "$file" "$(echo $file | sed -e 's/^ID_/SUBMIT_GO_ID_/')"

스타일 명령 보간법을 사용하기 때문에 $()최소한 POSIX 쉘이 필요하지만, 모든 곳에서 높은 수준의 쉘을 기대하는 것보다 "생각해내기"가 더 쉽습니다.

스크립트가 모든 Bourne 유형 셸에서 실행되어야 하는 경우 백틱 스타일 명령 보간으로 전환할 수 있습니다. 파일 이름에 공백이 포함되어 있으면 올바르게 수행하기 어려울 수 있지만 게시한 예에 따르면 다음과 같은 것 같습니다. 사실이 아니다. 따라서 귀하의 목적에 따라 이는 이전 옵션과 동일해야 합니다.

mv -i "$file" `echo $file | sed -e s/^ID_/SUBMIT_GO_ID_/`

밀리미터파

또 다른 옵션은 설치하는 것입니다mmv, 이 프로그램은 내가 아는 Unix 유형 시스템에는 설치되지 않지만 일반적으로 표준 패키지 저장소에 패키지되어 있습니다. 를 사용하면 mmv전체 쉘 스크립트 루프를 다음으로 바꿀 수 있습니다.

$ mmv 'ID_*' 'SUBMIT_GO_ID_#1'

모든 이름 바꾸기 요구는 지원되지 않으므로 -i플래그 가 없습니다 . mmv그러나 계획된 모든 이름 바꾸기를 사전 확인하고 작업을 시작하기 전에 문제를 감지하려고 시도하므로 아마도 귀하의 목적에 충분히 근접할 것입니다.

이름을 바꿔라

또 다른 옵션은 rename최소한 세 가지 변형으로 존재하는 명령입니다. 가지다 포크같은 이름의 Larry Wall의 Perl 스크립트. 그 중 하나는 Perl 배포판의 일부로 시스템에 이미 설치되어 있을 수 있습니다. 이후util-linux변형은 일반적으로 이 버전 대신 Linux 시스템에 설치되거나 그 옆에 설치됩니다. 둘 다 설치된 경우 prename충돌을 피하기 위해 Perl 기반 버전을 호출할 수 있습니다 .

Perl 기반의 주요 장점은 다음을 사용할 수 있다는 것입니다.펄 정규식mmv이는 지원되는 glob 표현식이나 지원되는 POSIX 정규 표현식보다 더 강력합니다 sed. 그러나 이 특정 예에서는 작업이 간단하기 때문에 중요하지 않습니다.

$ rename '^ID_' SUBMIT_GO_ID_ ID_EDMSCP_*.txt.pgp

util-linux버전은 첫 번째 인수를 "표현식"이라고 부르지만 POSIX 정규 표현식이나 Perl 정규 표현식이 아니기 때문에 훨씬 약합니다. 이는 전역 표현식도 아니며 단지 리터럴 문자열일 뿐입니다. 그러나 위에서 언급했듯이 이 특별한 경우에는 이 제한이 실제로 우리를 방해하지 않습니다.

$ rename ID_ SUBMIT_GO_ID_ ID_EDMSCP_*.txt.pgp

mmv와 마찬가지로 rename-i플래그는 지원되지 않습니다.

평범한 오래된 베른 껍질

요약하자면, 입력 패턴이 출력 패턴의 끝에 나타나므로 특정 사례에서는 더 간단한 솔루션이 가능하므로 이식 가능한 Bourne 쉘 구문을 사용하여 모든 작업을 수행할 수 있습니다.

for file in ID_EDMSCP_*.txt.pgp
do
    mv -i "$file" SUBMIT_GO_"$file"
done

쉘 언어의 내부 메커니즘이 항상 충분하지 않기 때문에 종종 필요한 복잡한 대안을 위에 남겨두었습니다.

답변2

이 시도:

for file in ID_EDMSCP_*.txt.pgp
do
    mv -i "${file}" SUBMIT_GO_"${file}"
done

답변3

Linux에서는 다음을 사용할 수 있습니다.rename주문하다. 매우 제한적이지만 이 간단한 사용 사례에는 충분합니다. 첫 번째 부분 문자열을 다른 문자열로 바꿉니다.

rename ID SUBMIT_GO_ID ID_EDMSCP_*.txt.pgp

Debian 및 그 파생 제품(Ubuntu, Mint 등)에서는 명령이 호출됩니다 rename.ul. 이러한 배포판의 명령은 rename호환되지 않는 구문을 사용하는 다른 명령입니다 .prename. 이 명령을 사용하면 다음을 수행할 수 있습니다.

prename 's/ID/SUBMIT_GO_ID/' ID_EDMSCP_*.txt.pgp

관련 정보