{"id":8806,"date":"2025-10-17T09:07:25","date_gmt":"2025-10-17T00:07:25","guid":{"rendered":"https:\/\/hasu0707.duckdns.org\/blog\/?p=8806"},"modified":"2025-10-17T09:07:27","modified_gmt":"2025-10-17T00:07:27","slug":"%ec%9e%90%eb%aa%a8%ea%b0%80-%eb%b6%84%eb%a6%ac%eb%90%9c-%ed%95%9c%ea%b8%80-%ed%8c%8c%ec%9d%bc%eb%aa%85-%ec%a1%b0%ed%95%a9","status":"publish","type":"post","link":"https:\/\/hasu0707.duckdns.org\/blog\/?p=8806","title":{"rendered":"\uc790\ubaa8\uac00 \ubd84\ub9ac\ub41c \ud55c\uae00 \ud30c\uc77c\uba85 \uc870\ud569"},"content":{"rendered":"\n<p>fix_hangul_filename.py<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import os\nimport sys\nimport unicodedata\n\ndef fix_hangul_in_filenames(directory: str, recursive: bool = False):\n    \"\"\"\n    \uc8fc\uc5b4\uc9c4 \ub514\ub809\ud1a0\ub9ac \ub0b4\uc5d0\uc11c \ud55c\uae00 \uc790\ubaa8\uac00 \ubd84\ub9ac\ub418\uc5b4 \uc788\ub294 \ud30c\uc77c\uba85\uc744 \ucc3e\uc544\n    \uc815\uc0c1\uc801\uc778 \ud55c\uae00 \ud615\ud0dc(NFC \ud615\ud0dc)\ub85c \ubcc0\ud658\ud558\ub294 \ud568\uc218\uc785\ub2c8\ub2e4.\n\n    \ub9e4\uac1c\ubcc0\uc218:\n        directory (str): \uac80\uc0ac\ud560 \ub514\ub809\ud1a0\ub9ac\uc758 \uacbd\ub85c\n        recursive (bool): \ud558\uc704 \ub514\ub809\ud1a0\ub9ac\uae4c\uc9c0 \ud3ec\ud568\ud560\uc9c0 \uc5ec\ubd80 (\uae30\ubcf8\uac12: False)\n    \"\"\"\n\n    # 1. \uc9c0\uc815\ub41c \uacbd\ub85c\uac00 \uc2e4\uc81c\ub85c \uc874\uc7ac\ud558\ub294 \ub514\ub809\ud1a0\ub9ac\uc778\uc9c0 \ud655\uc778\n    if not os.path.isdir(directory):\n        print(f\"\u274c \uc9c0\uc815\ud55c \uacbd\ub85c\uac00 \ub514\ub809\ud1a0\ub9ac\uac00 \uc544\ub2d9\ub2c8\ub2e4: {directory}\")\n        return\n\n    # 2. os.walk()\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub514\ub809\ud1a0\ub9ac \ub0b4\uc758 \ud30c\uc77c \ubaa9\ub85d\uc744 \uc21c\ud68c\n    #    recursive=False\uc774\uba74 \ud558\uc704 \ud3f4\ub354\ub294 \ud0d0\uc0c9\ud558\uc9c0 \uc54a\uc74c\n    for root, dirs, files in os.walk(directory):\n        for name in files:\n            # 3. \ud30c\uc77c\uba85\uc744 \uc720\ub2c8\ucf54\ub4dc \uc815\uaddc\ud654(NFC)\ud558\uc5ec \ud55c\uae00 \uc790\ubaa8\ub97c \uc870\ud569\n            normalized_name = unicodedata.normalize('NFC', name)\n\n            # 4. \uc6d0\ub798 \uc774\ub984\uacfc \uc815\uaddc\ud654\ub41c \uc774\ub984\uc774 \ub2e4\ub97c \uacbd\uc6b0\uc5d0\ub9cc \uc218\uc815 \uc218\ud589\n            if name != normalized_name:\n                old_path = os.path.join(root, name)\n                new_path = os.path.join(root, normalized_name)\n\n                try:\n                    # 5. \ud30c\uc77c \uc774\ub984 \ubcc0\uacbd (rename)\n                    os.rename(old_path, new_path)\n                    print(f\"\u2705 \ud30c\uc77c\uba85 \uc218\uc815 \uc644\ub8cc: '{name}' \u2192 '{normalized_name}'\")\n\n                except Exception as e:\n                    # 6. \uad8c\ud55c \ubb38\uc81c\ub098 \uc911\ubcf5 \ud30c\uc77c\uba85 \ub4f1\uc73c\ub85c \uc2e4\ud328\ud560 \uacbd\uc6b0 \uc608\uc678 \ucc98\ub9ac\n                    print(f\"\u26a0\ufe0f \ud30c\uc77c\uba85 \ubcc0\uacbd \uc2e4\ud328: '{name}' \u2192 '{normalized_name}' ({e})\")\n\n        # recursive=False\uc774\uba74 \ud604\uc7ac \ub514\ub809\ud1a0\ub9ac\uae4c\uc9c0\ub9cc \uc218\ud589\n        if not recursive:\n            break\n\n\nif __name__ == \"__main__\":\n    \"\"\"\n    \uba85\ub839\ud589\uc5d0\uc11c \uc2e4\ud589\ud560 \ub54c\uc758 \uc9c4\uc785\uc810.\n    \uc0ac\uc6a9\uc790\uac00 \uc778\uc218\ub85c \ub514\ub809\ud1a0\ub9ac \uacbd\ub85c\ub97c \uc9c0\uc815\ud574\uc57c \ud568.\n    \uc608:\n        python fix_hangul_filename.py \"C:\\\\Videos\"\n        python fix_hangul_filename.py \"\/Users\/junseok\/Downloads\" --recursive\n    \"\"\"\n\n    # \uc778\uc790\uac00 \ucda9\ubd84\ud788 \uc8fc\uc5b4\uc9c0\uc9c0 \uc54a\uc558\uc744 \uacbd\uc6b0 \uc548\ub0b4 \uba54\uc2dc\uc9c0 \ucd9c\ub825\n    if len(sys.argv) &lt; 2:\n        print(\"\uc0ac\uc6a9\ubc95: python fix_hangul_filename.py &lt;\ub514\ub809\ud1a0\ub9ac\uacbd\ub85c> [--recursive]\")\n        sys.exit(1)\n\n    # \uccab \ubc88\uc9f8 \uc778\uc790\ub294 \ub514\ub809\ud1a0\ub9ac \uacbd\ub85c\n    target_dir = sys.argv[1]\n\n    # '--recursive' \uc635\uc158\uc774 \ud3ec\ud568\ub418\uc5b4 \uc788\uc73c\uba74 \ud558\uc704 \ud3f4\ub354\uae4c\uc9c0 \ucc98\ub9ac\n    recursive = \"--recursive\" in sys.argv\n\n    print(f\"\ud83d\udd0d \ub514\ub809\ud1a0\ub9ac \uac80\uc0ac \uc2dc\uc791: {target_dir}\")\n    if recursive:\n        print(\"\u21b3 \ud558\uc704 \ub514\ub809\ud1a0\ub9ac\uae4c\uc9c0 \ud3ec\ud568\ud558\uc5ec \uac80\uc0ac\ud569\ub2c8\ub2e4.\")\n    else:\n        print(\"\u21b3 \ud604\uc7ac \ub514\ub809\ud1a0\ub9ac\ub9cc \uac80\uc0ac\ud569\ub2c8\ub2e4.\")\n\n    # \ud30c\uc77c\uba85 \ubcf5\uc6d0 \uc2e4\ud589\n    fix_hangul_in_filenames(target_dir, recursive)\n\n    print(\"\u2705 \ubaa8\ub4e0 \ud30c\uc77c \uac80\uc0ac \uc644\ub8cc.\")\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>fix_hangul_filename.py<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[40,14],"tags":[],"class_list":["post-8806","post","type-post","status-publish","format-standard","hentry","category-os_win","category-computing_tipsandtricks"],"_links":{"self":[{"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/8806","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8806"}],"version-history":[{"count":0,"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/8806\/revisions"}],"wp:attachment":[{"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8806"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8806"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hasu0707.duckdns.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8806"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}