파일 세트의 모든 콜론을 대시로 바꾸시겠습니까?

파일 세트의 모든 콜론을 대시로 바꾸시겠습니까?

다음 명령을 사용하여 특정 하위 폴더의 파일 이름에 있는 모든 콜론을 대시로 바꾸려고 했습니다.

find . -type f -name "*:*" -exec rename -n 's/:/-/g' {} +

하지만 오류 메시지가 나타납니다.

rename: not enough arguments

인터넷 검색에 따르면 이름이 변경된 버전이 위 명령에 필요한 버전과 다르기 때문인 것 같습니다. 그렇다면 이 명령을 이름이 바뀐 버전에서 작동하는 명령으로 "변환"하려면 어떻게 해야 합니까?

내 이름이 바뀐 버전은 "util-linux 2.28.2에서 이름 바꾸기"입니다.

답변1

rename예, Linux 시스템에는 관련이 없고 완전히 호환되지 않는 두 가지 주요 명령 변형이 있습니다.

하나 (수십 년 전에 샘플 스크립트로 시작하여 오랫동안 perl함께 배포되었지만 이제는 일부 확장이 포함된 하나 이상의 독립 실행형 패키지로 제공됩니다). perl이것은 시스템에서 호출 rename되거나 때로는 다른 것으로 호출됩니다.prenamerename

이것이 명령줄에서 기대하는 것입니다.

rename그리고 의 유용성은 매우 제한적입니다 util-linux. 이는 rename.ul일부 시스템에서 호출되는 경우도 있습니다.renameperlrename

이 문자열을 사용하면 한 문자열을 다른 문자열로만 바꿀 수 있습니다. 이렇게 할 수 있지만 -execdir rename : - {} +이는 콜론( 12:30:00.log-> 12-30:00.log)만 대체합니다.

rename여기에서 수동으로 구현할 수 있습니다 .

find . -name '*:*' -type f -print0 | perl -0ne '
  rename $_, s{[^/]+$}{$& =~ y/:/-/r}res or warn "rename $_: $!"'

(여기서는 파일의 기본 이름에서 :s만 바꾸 십시오. 마치 디렉토리에 s가 ​​포함되어 있으면 실패할 것입니다.)-:

perl또는 rename을 바꾸고 호출하는 대신 쉘을 사용하십시오 mv(여기에서는 bash및 ksh 매개변수 확장 연산자를 사용합니다. 그렇지 않은 경우 사용 하거나 바꿀 ${var//pattern/replacement}수 있습니다 ).bashkshzshbash

find . -name '*:*' -type f -exec bash -c '
  for file do
    base=${file##*/}
    mv "$file" "${file%/*}/${base//:/-}"
  done' bash {} +

또는 zsh해당 zmv기능을 사용하십시오.

autoload zmv
zmv '(**/)(*:*)(#qD.)' '$1${2//:/-}'

답변2

아니요 rename:

find . -type f -name '*:*' -execdir bash -c 'echo mv "$1" "${1//:/-}"' bash {} \;

표시된 대로 시도해 보고 echo제대로 작동한다고 생각되면 제거하세요.

이것은 발견된 각 파일 이름을 인수로 사용하여 -execdir실행하는 데 사용됩니다. bash -c 'mv "$1" "${1//:/-}"'에 의해 생성된 내부 쉘은 bash -cin이라는 이름을 받고 해당 이름으로 확장 $1되어 모두 .${1//:/-}:-

(명령 끝에 있는 꼬리는 서브쉘에 bash제공되는 것 입니다.)$0bash -c

관련 정보