이러한 파일 목록이 포함된 폴더가 있습니다.
lesson1.mp4
lesson2.mp4
lesson3.mp4
lesson4.mp4
"rename.txt"의 내용을 기반으로 이 파일의 이름을 바꾸려고 합니다.
1. Introduction to the React Ecosystem Video
2. Video Babel, Webpack, and React
3. Solution - Props
4. Solution - .map and .filter
이 스크립트를 실행 중입니다.
for file in *.mp4;
do read line;
mv -v "${file}" "${line}";
done < rename.txt
이것은 나에게 원치 않는 결과를 제공합니다
'lesson1.mp4' -> '1. Introduction to the React Ecosystem Video '
'lesson10.mp4' -> '2. Video Babel, Webpack, and React '
'lesson11.mp4' -> '3. Solution - Props '
'lesson12.mp4' -> '4. Solution - .map and .filter '
'lesson13.mp4' -> '5. Video Validating Components with PropTypes'
원하는 결과.
'lesson1.mp4' -> '1. Introduction to the React Ecosystem Video.mp4'
'lesson2.mp4' -> '2. Video Babel, Webpack, and React.mp4'
'lesson3.mp4' -> '3. Solution - Props.mp4'
'lesson4.mp4' -> '4. Solution - .map and .filter.mp4'
'lesson5.mp4' -> '5. Video Validating Components with PropTypes.mp4'
답변1
와일드카드 대신 셸 확장을 사용할 수 있습니다.
for file in lesson{1..10}.mp4;do
read line
mv -v "${file}" "${line}"
done < rename.txt
오류가 발생하기 쉬운 것처럼 보일 수 있지만 이 작업을 수행해야 하는 파일이 많은 경우 파일 이름의 숫자를 이름이 바뀐 파일의 줄 시작 부분에 있는 숫자와 일치시키는지 확인할 수 있습니다. 그것은 다음과 같습니다:
for file in *.mp4;do
num=$(echo "${file}" | sed -E 's/^lesson([0-9]+).mp4$/\1/')
line=$(grep -E "^ *${num}\." rename.txt)
mv -v "${file}" "${line}"
done
이런 방식으로 파일의 순서는 중요하지 않으며 rename.txt
쉘 전역 파일 이름의 순서도 중요하지 않습니다.
답변2
이 답변은 -v
옵션을 사용하여 ls
파일 목록의 올바른 숫자 순서를 보장합니다. 각 파일 이름은 쉘 위치 인수에 배치됩니다. 각 인수에 전체 파일 이름이 포함되도록 하기 위해 쉘의 "내부 필드 구분 기호"를 일시적으로 변경하므로 최종 파일 이름에 공백이 포함되어 있어도 계속 작동합니다. 마지막으로, 나는 공백이 포함된 파일 이름을 싫어하기 때문에(그리고 비슷한 본능을 개발하는 것이 더 나을 것임) 모든 포함된 공백을 밑줄로 변환합니다. 이 shift
명령은 단순히 모든 위치 인수의 값을 앞으로 팝하여 $1
목록의 다음 값을 가져옵니다.
oldifs="${IFS}"
IFS=$'\n'
set $(ls -v1 lesson*)
while read line ; do
mv "$1" "${line// /_}"
shift
done < rename.txt
IFS="${oldifs}"