제목이 파일 번호 앞에 나타나기 때문에 파일 순서가 잘못된 여러 디렉터리가 있습니다. 확장자를 제외한 모든 파일을 마지막에 일치시키고 교체하고 싶기 때문에 숫자는 아래와 같이 시작 부분에 있습니다.
따라서;
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
-execdir
find
문서디렉토리 자체 내에서 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
수 있습니다 .-p
mv
bash
파일 목록을 사용하여 Ubuntu , Mac OS High Sierra 및 Mac OS High Sierra 에서 이 구현을 테스트하고 sh
파일을 다른 하위 디렉터리에 배치하고 일부 자격이 없는 파일을 추가했습니다.bash
sh