여러 디렉터리의 파일 이름 바꾸기

여러 디렉터리의 파일 이름 바꾸기

제목이 파일 번호 앞에 나타나기 때문에 파일 순서가 잘못된 여러 디렉터리가 있습니다. 확장자를 제외한 모든 파일을 마지막에 일치시키고 교체하고 싶기 때문에 숫자는 아래와 같이 시작 부분에 있습니다.

따라서;

A guide to perfect eggs-456704.mp4
Boil an egg-456702.mp4
How to ruin scrambled eggs-456703.mp4
Make green eggs and ham-456701.mp4
Poached eggs-456705.mp4

이와 관련하여:

456701-Make green eggs and ham.mp4
456702-Boil an egg.mp4
456703-How to ruin scrambled eggs.mp4
456704-A guide to perfect eggs.mp4
456705-Poached eggs.mp4

공백이 있는 각 파일에는 임의의 헤더 길이가 있습니다. 숫자는 ".mp4" 확장자 앞의 6자리이지만 헤더 뒤에는 대시가 있습니다.

답변1

사용find그리고Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion.

find * -type f -name "*.mp4" -exec bash -c 'echo mv -v "$1" "${1//[^0-9]}-${1//[\-0-9]}"' _ '{}' \;
  • 숫자를 제외한 모든 것을 제거 ${1//[^0-9]}합니다. is는 //전역 대체 구문이며 /숫자가 처음 나타나는 경우에만 사용됩니다.

  • 그런 다음 대시/하이픈을 사용 -하여 a 또는 숫자 ${1//[\-0-9]}인 모든 항목을 제거합니다 ( 파일 이름에 a와 숫자 부분만 있다고 가정).--

위에서 사용한 명령은 -exec어떤 이유로 안전하지 않습니다.1,2여기서 Shell Substitution Expansion을 사용하면 파일 경로를 사용하여 예기치 않은 이름 변경이 발생하고 -파일 이름에 있는 모든 대시가 제거됩니다!

echo마지막으로 테스트 실행에 사용된 위치에서 실제 이름 바꾸기를 수행하려면 명령에서 위 항목을 제거하는 것을 잊지 마십시오 .


find . -type f -name "*.mp4" -execdir sh -c '
    n="${1##*-}";fn="${1%-*}"; 
    echo mv -v "$1" "${n%.*}-${fn##*/}.mp4" ' _ '{}' \;

이전과 동일한 명령이지만 여기서는 다음을 사용합니다.shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion이렇게 하면 제거해야 하는 마지막 대시를 제외하고 -파일 이름의 모든 대시가 그대로 유지됩니다 (있는 경우).a file-with -- here-006.file

-type f다음으로 끝나는 파일을 찾고 있습니다 . 즉, 현재 디렉토리를 다음으로 변경합니다..mp4-execdirfind문서디렉토리 자체 내에서 sh -c ' ... '를 찾아 실행합니다.

  • "cut-up-to-last-prefix" 사용 : n="${1##*-}"파일 이름의 시작부터 마지막 ​​대시까지 모든 것을 제거하고 변수에 -할당 하거나 현재 디렉토리로 돌아가는 상대 경로입니다 .-n$1${1}./fileName-execdir sh -c '...' _ '{}' \;

  • "cut-up-to-first-suffix" 사용 : 첫 번째 대시와 그 자체가 보일 fn="${1%-*}"때까지 파일 이름 끝에서 모든 것을 제거하고 변수에 할당합니다 .--fn

    이제 n="456704.mp4"( nf="./A guide to perfect eggs"첫 번째 파일을 가정). 그 다음에;

  • 첫 번째 점과 그 자체가 보일 ${n%.*}-때까지 fileName 끝에서 모든 것을 제거한 다음 대시 를 추가합니다 . 따라서 이것은 fileName 의 숫자 부분만 생성합니다 ...-456704

  • ${fn##*/}.mp4파일 이름 요청부터 /마지막 ​​슬래시와 그 자체를 확인한 다음 끝에 추가하는 것까지 /모든 것을 제거 합니다 . .mp4그렇기 때문에 이런 결과가 나오는 것입니다 A guide to perfect eggs.mp4.


1 사용 시 어떤 보안 문제와 경쟁 조건이 존재합니까 find -exec?
2 PATH의 디렉터리에 대해 "-execdir" 작업을 사용하는 것이 안전하지 않은 이유는 무엇입니까?

답변2

이를 수행하는 방법은 다음과 같습니다. 테스트되지 않은

#!/bin/bash

files=(*file)

for f in "${files[@]}" 
  do 
     get_ext="${f##*.}"
     no_ext="${f%-*}"
     n="${f##*-}" nn="${n%.*}"
     mv "$f" "$nn-$no_ext.$get_ext"
 done

답변3

set "a file blah blah-004.file" \
"b file blah blah blah-002.file" \
"c file blahh blah-003.file" \
"d file blah blah blah blabby blah-001.file" \
"e file blah-005.file"

for name; do
  old=$name                 # save old name
  ext=${name##*.}           # take extension
  name=${name%.*}           # remove extension
  number=${name##*-}        # take number
  name=${name%-*}           # remove number
  new="$number-$name.$ext"  # set new name
  echo mv "$old" "$new"     # test rename
done

echo유효한 경우 마지막 항목을 삭제하세요.

답변4

이는 이식 가능한 sh구현입니다.

find . -name "*[0-9].mp4" |
    sed "s/\(.*\/\)\(.*\)-\([0-9]*\)\.mp4/'\1\2-\3.mp4' '\1\3-\2.mp4'/" |
    xargs -p -L 1 mv -v

명령 은 매우 간단합니다. 확장자 앞에 숫자가 하나 이상 포함된 파일 find만 반환합니다 ..mp4

sed명령은 각 파일 이름을 작은따옴표로 묶어 파일 이름을 복사한 다음 두 번째 파일 이름은 그에 따라 상대 파일 경로와 파일 이름 사이의 숫자 부분을 이동합니다(예: './a/Boil an egg-456707' './a/456707-Boil an egg.mp4').

그러면 현재 파일 이름과 새 파일 이름의 결과 목록이 xargs실행될 명령 에 전달됩니다 mv -v. 이 옵션은 한 번에 한 줄을 처리하는 -L 1데 필요합니다 . 이 명령에서 옵션을 제거하고 사용해야 하는 옵션을 변경할 xarg수 있습니다 .-pmv

bash파일 목록을 사용하여 Ubuntu , Mac OS High Sierra 및 Mac OS High Sierra 에서 이 구현을 테스트하고 sh파일을 다른 하위 디렉터리에 배치하고 일부 자격이 없는 파일을 추가했습니다.bashsh

관련 정보