최상위 다운로드 파일을 확장자별 폴더로 분류하려면 바로 아래에 있는 파일을 확인하고 txt, csv 같은 폴더를 만든 다음 기존 대상 이름은 건너뛰는 스크립트를 사용하세요. 아래의 폐기 가능한 예제로 시작해 이동 항목을 미리 확인한 다음 터미널이나 Apple 단축어에서 실행하세요.
이 안내는 기존 하위 폴더와 그 안의 파일은 그대로 두면서 흩어진 파일을 폴더로 실제 이동하려는 Mac 사용자를 위한 것입니다. 주요 판단 자료는 미리 보기 보고서입니다. 처리 대상 파일마다 이동 예정 위치가 표시되고, 충돌하거나 지원되지 않는 이름은 건너뛴다는 메시지가 명시적으로 표시됩니다.
어떤 항목이 이동되고, 어떤 항목이 그대로 남나요?
Finder에서는 정렬 및 그룹화 제어 기능과 폴더, 스마트 폴더를 사용할 수 있습니다. Apple 설명에 따르면 스마트 폴더는 일치하는 파일을 한데 모아 보여 주지만 파일을 이동하지는 않습니다. 이 작업의 목표는 파일을 실제로 옮겨 담은 확장자별 폴더를 만드는 것입니다. Mac의 Finder에서 파일 정리하기.
예제를 확인하기 전에 Finder를 열고 Finder > 설정 > 고급을 선택한 다음 모든 파일 확장자 보기를 선택하세요. 그러면 분류기에 사용되는 접미사가 표시됩니다. 확장자를 표시해도 파일 형식은 바뀌지 않습니다. Mac에서 파일 확장자 표시 또는 가리기.
아래 스크립트는 다음과 같은 명시적인 규칙을 사용합니다. 이는 이 구현에 적용되는 규칙이며, Finder나 단축어의 보편적인 동작을 설명하는 것은 아닙니다.
| 발견된 항목 | 분류기의 동작 |
|---|---|
note.TXT 같은 일반적인 바로 아래 파일 |
txt/note.TXT로 이동할 예정으로 표시하고 원래 파일 이름을 유지합니다 |
bundle.tar.gz 같은 복합 이름 |
마지막 접미사를 사용합니다. gz/bundle.tar.gz |
| 마침표가 없거나 마침표로 끝나는 파일 | 그대로 두고 건너뛴다고 표시합니다 |
| 확장자 이름이 붙은 폴더를 포함한 폴더 | 폴더와 그 안의 파일을 그대로 둡니다 |
| 점으로 시작하는 이름 | 검사에서 제외합니다 |
| 심볼릭 링크 | 그대로 둡니다 |
| ASCII 문자와 숫자 이외의 문자가 포함되거나 32자보다 긴 확장자 | 그대로 두고 건너뛴다고 표시합니다 |
| 같은 파일 이름을 가진 대상 항목이 이미 있는 경우 | 원본 파일을 그대로 두고 충돌로 표시합니다 |
| 일반 파일이나 심볼릭 링크가 차지하고 있는 대상 폴더 이름 | 폴더가 막혀 있다고 표시하고 원본 파일을 그대로 둡니다 |
확장자를 제한하면 폴더 이름 지정 규칙이 간단하고 예측 가능해집니다. 건너뛴 파일은 수동으로 처리할 수 있도록 남아 있습니다. 스크립트는 대체 이름을 임의로 만들거나 파일을 조용히 삭제하지 않습니다.
다운로드 폴더에 테스트용 예제 만들기
터미널을 열고 아래 설정 블록 전체를 붙여 넣으세요. Downloads/ExtensionSortDemo 안에 합성 텍스트 파일만 생성합니다. .gz 같은 예시 확장자가 붙은 파일도 내용은 해당 형식의 예제가 아니라 일반 샘플 텍스트입니다. 데모 폴더가 이미 있으면 설정을 중단하므로, 다시 실행해도 이전 테스트를 초기화하지 않습니다.
Apple 설명에 따르면 터미널은 명령 및 셸 스크립트를 실행하는 방법이며, mv는 로컬 파일을 이동하는 용도로 사용됩니다. 여기서는 터미널을 사용해 실제 이동을 수행하기 전에 계획된 각 이동을 읽기 쉬운 방식으로 미리 확인합니다. Mac의 터미널이란 무엇인가요?, Mac의 터미널에서 파일 관리하기.
/bin/bash <<'BASH'
set -eu
demo="$HOME/Downloads/ExtensionSortDemo"
/bin/mkdir "$demo"
/bin/mkdir "$demo/nested" "$demo/txt"
printf 'sample text\n' > "$demo/sample.txt"
printf 'uppercase suffix example\n' > "$demo/note.TXT"
printf 'name,value\nblue,1\n' > "$demo/palette.csv"
printf 'synthetic compound-name example\n' > "$demo/bundle.tar.gz"
printf 'no extension example\n' > "$demo/README"
printf 'trailing dot example\n' > "$demo/trailing."
printf 'hidden example\n' > "$demo/.hidden.txt"
printf 'nested example\n' > "$demo/nested/inside.txt"
printf 'existing destination example\n' > "$demo/txt/sample.txt"
printf 'blocks creation of a csv folder\n' > "$demo/csv"
printf 'Created demo folder: %s\n' "$demo"
BASH
Finder에서 다운로드 폴더를 열고 ExtensionSortDemo를 여세요. sample.txt라는 이름의 파일이 두 개 있는 것을 확인하세요. 하나는 데모 폴더의 최상위에 있고 다른 하나는 이미 txt 안에 있습니다. csv은 파일이라는 점도 확인하세요. 이 항목들은 이동을 건너뛰어야 하는 흔한 이유 두 가지를 테스트하기 위한 것입니다.
파일을 이동하기 전에 분류기 미리 보기
아래의 전체 프로그램을 터미널에 붙여 넣으세요. 처음에는 설정값이 mode=preview이므로 확장자별 폴더를 만들거나 파일을 이동하지 않고 예정된 이동만 표시합니다. 설정된 경로는 다운로드 폴더 전체가 아니라 폐기 가능한 데모 폴더입니다.
/bin/bash <<'BASH'
set -u
export LC_ALL=C
unset GLOBIGNORE
shopt -s nullglob
shopt -u dotglob
root="$HOME/Downloads/ExtensionSortDemo"
mode=preview
case "$mode" in
preview|move) ;;
*) printf 'Invalid mode\n' >&2; exit 1 ;;
esac
if [ ! -d "$root" ] || [ -L "$root" ]; then
printf 'Root must be an existing ordinary folder\n' >&2
exit 1
fi
for file in "$root"/*; do
if [ -L "$file" ] || [ ! -f "$file" ]; then
printf 'SKIP non-regular: %q\n' "$file"
continue
fi
name=${file##*/}
case "$name" in
*.*) ext=${name##*.} ;;
*) printf 'SKIP no extension: %q\n' "$name"; continue ;;
esac
case "$ext" in
''|*[!A-Za-z0-9]*)
printf 'SKIP unsupported extension: %q\n' "$name"
continue ;;
esac
if [ "${#ext}" -gt 32 ]; then
printf 'SKIP long extension: %q\n' "$name"
continue
fi
ext=$(printf '%s' "$ext" | /usr/bin/tr '[:upper:]' '[:lower:]')
folder="$root/$ext"
dest="$folder/$name"
if [ -L "$folder" ] || { [ -e "$folder" ] && [ ! -d "$folder" ]; }; then
printf 'SKIP blocked folder: %q\n' "$folder"
continue
fi
if [ -e "$dest" ] || [ -L "$dest" ]; then
printf 'SKIP collision: %q\n' "$dest"
continue
fi
if [ "$mode" = preview ]; then
printf 'WOULD MOVE %q -> %q\n' "$file" "$dest"
continue
fi
/bin/mkdir -p "$folder" || exit 1
/bin/mv -n "$file" "$dest" || exit 1
if [ -e "$file" ] || [ -L "$file" ]; then
printf 'NOT MOVED: %q\n' "$file" >&2
exit 1
fi
printf 'MOVED %q -> %q\n' "$file" "$dest"
done
printf 'Finished (%s). Review all SKIP lines.\n' "$mode"
BASH
즉시 하위 항목을 지정하는 패턴 "$root"/*는 디렉터리 안으로 들어가지 않습니다. 이어지는 파일 검사는 디렉터리와 심볼릭 링크를 제외합니다. nullglob은 빈 폴더에서도 일치하지 않는 패턴을 파일 이름으로 잘못 처리하지 않도록 합니다. dotglob을 비활성화하면 점으로 시작하는 이름이 제외됩니다. 이러한 동작은 Apple이 배포한 Bash 설명서에 나와 있습니다. Bash 설명서.
스크립트는 마지막 접미사를 추출하고 tr으로 문자를 소문자로 바꿉니다. 따라서 note.TXT는 파일 이름을 유지한 채 txt 폴더로 이동합니다. Apple의 tr 설명서에는 여기에서 사용하는 대문자에서 소문자로의 문자 매핑이 나와 있습니다. tr(1) — 문자 변환.
이 테스트 데이터에서 예상되는 주요 결과는 다음과 같습니다.
| 합성 원본 파일 | 예상 미리 보기 결과 |
|---|---|
note.TXT |
txt/note.TXT로 이동 예정 |
bundle.tar.gz |
gz/bundle.tar.gz로 이동 예정 |
sample.txt |
txt/sample.txt와 충돌하므로 건너뜀 |
palette.csv |
csv 폴더 이름이 파일에 막혀 있으므로 건너뜀 |
README |
확장자가 없으므로 건너뜀 |
trailing. |
확장자가 비어 있으므로 건너뜀 |
nested/inside.txt |
검사하지 않음 |
.hidden.txt |
검사하지 않음 |
이 결과는 예상되는 파일 시스템 동작이며, 준비 과정에서 이동을 실제로 실행했다는 뜻은 아닙니다. 프로그램은 Bash 구문 검사를 통과했고, 별도의 결정론적 파일 이름 매핑 검사에서 접미사 추출과 소문자 변환이 확인되었습니다. 이 준비 환경은 읽기 전용이었으므로 전체 macOS 파일 이동 절차를 실행하지는 않았습니다.
예제 파일 이동 후 결과 확인하기
미리 보기 결과가 표와 일치하면 mode=preview만 mode=move로 바꾸고 같은 전체 프로그램을 다시 붙여 넣으세요. 이 테스트에서는 데모 경로를 그대로 유지하세요.
이동 모드에서 mkdir -p는 필요한 폴더를 만들거나 기존 디렉터리를 그대로 사용합니다. 기존 일반 파일을 폴더로 바꾸지는 않으므로, 스크립트는 먼저 대상 폴더를 확인합니다. mkdir(1) — 디렉터리 만들기.
이동에는 기존 파일을 덮어쓰지 않는 것으로 문서화된 macOS의 mv -n을 사용합니다. 앞선 존재 여부 검사에서 충돌 메시지를 읽기 쉽게 표시하고, 그다음 원본이 남아 있는지 검사해 이동에 실패한 경우를 확인합니다. 명령 실행 실패가 보고되면 프로그램을 중단합니다. mv(1) — 파일 이동.
Finder에서 데모 폴더를 확인하세요. note.TXT은 txt 안에 있고, bundle.tar.gz은 새로 만든 gz 폴더 안에 있어야 합니다. sample.txt 두 버전은 원래 위치에 그대로 있어야 합니다. palette.csv은 최상위에 남아 있어야 하고, nested/inside.txt는 nested 안에 그대로 있어야 합니다.
마지막의 Finished 줄은 검사가 완료되었다는 뜻입니다. 건너뛴 항목 메시지도 확인하세요. 분류기를 다시 실행하면 이미 분류된 파일이 들어 있는 폴더는 재귀적으로 검사하지 않으므로 파일은 그대로 폴더 안에 남습니다.
Apple 단축어에서 같은 분류기 실행하기
단축어를 이 스크립트를 실행하는 버튼으로 사용할 수 있습니다. Apple 설명에 따르면 단축어 편집기에는 셸 스크립트를 작성하고 실행하는 기능이 내장되어 있습니다. 확장자 매핑과 존재 여부 검사는 셸 프로그램이 처리합니다. 이 문서에서는 기본 파일 이동 동작도 충돌 상황에서 똑같이 동작한다고 가정하지 않습니다. macOS용 단축어 알아보기.
단축어를 직접 만들고 테스트하는 동안에는 데모 경로를 지정해 두세요.
- 단축어를 열고 추가 버튼을 클릭한 다음 단축어 이름을
확장자별 데모 분류로 지정합니다. - 동작 목록에서
Run Shell Script를 검색해 추가합니다. - 셸을
/bin/bash로 설정합니다. 위의 분류기 블록 전체를 여는/bin/bash줄과 마지막BASH구분자를 포함해 스크립트 입력란에 붙여 넣습니다. 처음에는mode=preview를 그대로 둡니다. - 스크립트 동작 뒤에
Quick Look을 추가하고 스크립트 출력을 입력으로 연결합니다. - 단축어를 실행하고 스크립트를
mode=move로 변경하기 전에 미리 보기 보고서를 확인합니다.
Apple은 동작을 추가하고 테스트해 사용자 설정 단축어를 만드는 방법을 안내하며, 동작 간 전달되는 내용을 확인할 때 Quick Look을 권장합니다. Mac에서 사용자 설정 단축어 만들기, Mac의 단축어에서 동작 테스트하기.
이 단축어에는 입력 파일이 필요하지 않습니다. 경로가 스크립트 안에 정의되어 있기 때문입니다. 실행이 성공하면 텍스트 보고서가 출력되며 Quick Look에서 표시됩니다. 이 보고서는 다른 파일 동작으로 전달할 이동된 파일 객체 모음이 아닙니다. 설치된 버전에서 동작이 어떤 입력을 받고 어떤 출력을 만드는지 확인하려면 Apple 설명대로 해당 동작의 아이콘을 Control-클릭하고 정보 보기를 선택하세요. Mac의 단축어에서 동작 목록 탐색하기.
단축어에서 스크립트 실행을 활성화해야 한다면 Apple이 안내하는 설정은 단축어 > 설정 > 고급 > 스크립트 실행 허용입니다. 설치된 환경에서 셸 동작을 사용할 수 없다면 위의 전체 터미널 프로그램을 사용하세요. 동일한 분류 작업을 독립적으로 수행합니다. Mac의 단축어에서 고급 개인정보 보호 및 보안 설정 변경하기.
최상위 다운로드 파일에 규칙 적용하기
테스트용 예제를 확인한 뒤 실제 다운로드 폴더에 적용할 때는 분류기 안의 경로 한 줄을 다음과 같이 바꾸면 됩니다. 이 코드는 설정 일부이며 독립적으로 실행되는 분류 프로그램이 아닙니다.
root="$HOME/Downloads"
경로를 바꿀 때마다 mode=preview으로 돌아오세요. 이동을 활성화하기 전에 예정된 대상 경로와 건너뛰기 메시지를 모두 확인하세요. 프로그램은 처리 가능한 바로 아래 파일을 일괄 처리하며, 개별 파일을 선택하는 메시지는 표시하지 않습니다.
다운로드가 완료된 파일이 들어 있는 폴더에서 수동 일괄 작업으로 실행하세요. 스크립트는 다운로드 완료 여부를 판별하거나, 새 항목을 감시하거나, 동시 실행을 조정하지 않습니다. 검사와 이동은 별개의 작업이므로 실행 중에는 다른 파일 이동 작업이 해당 폴더에서 이루어지지 않도록 하세요. 미리 보기는 현재 상태를 보여 주는 보고서이지 대상 경로를 예약하는 기능이 아닙니다.
충돌이 발생하면 Finder에서 두 파일을 확인하고 최상위 파일 이름을 바꿀지, 원래 위치에 둘지 결정하세요. 확장자별 폴더를 만들 수 없는 경우에는 해당 이름을 차지하고 있는 항목을 처리한 뒤 다시 실행하세요. 두 경우 모두 프로그램이 파일을 덮어쓰도록 변경할 필요는 없습니다.
마지막으로 Finder에서 실제 대상 폴더를 확인하고 최상위에 남은 파일을 보고서와 비교하세요. 테스트용 예제를 통해 구체적으로 확인할 수 있습니다. 의도한 파일은 이동되고, 기존 이름은 그대로 유지되며, 하위 폴더의 내용은 원래 위치에 남습니다.
출처
- Mac의 Finder에서 파일 정리하기 — Apple 지원.
- Mac에서 파일 확장자 표시 또는 가리기 — Apple 지원.
- Mac의 터미널이란 무엇인가요? — Apple 지원.
- Mac의 터미널에서 파일 관리하기 — Apple 지원.
- Bash 설명서 — Apple OSS Distributions.
- tr(1) — 문자 변환 — Apple OSS Distributions.
- mkdir(1) — 디렉터리 만들기 — Apple OSS Distributions.
- mv(1) — 파일 이동 — Apple OSS Distributions.
- macOS용 단축어 알아보기 — Apple Developer.
- Mac에서 사용자 설정 단축어 만들기 — Apple 지원.
- Mac의 단축어에서 동작 테스트하기 — Apple 지원.
- Mac의 단축어에서 동작 목록 탐색하기 — Apple 지원.
- Mac의 단축어에서 고급 개인정보 보호 및 보안 설정 변경하기 — Apple 지원.