<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
	<id>https://devcafe.co.kr/w/index.php?action=history&amp;feed=atom&amp;title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89</id>
	<title>파이썬 폴더 내부 텍스트 검색 - 편집 역사</title>
	<link rel="self" type="application/atom+xml" href="https://devcafe.co.kr/w/index.php?action=history&amp;feed=atom&amp;title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89"/>
	<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89&amp;action=history"/>
	<updated>2026-05-19T08:17:09Z</updated>
	<subtitle>이 문서의 편집 역사</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://devcafe.co.kr/w/index.php?title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89&amp;diff=2318&amp;oldid=prev</id>
		<title>2025년 9월 26일 (금) 07:09에 Devcafe님의 편집</title>
		<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89&amp;diff=2318&amp;oldid=prev"/>
		<updated>2025-09-26T07:09:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ko&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← 이전 판&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2025년 9월 26일 (금) 16:09 판&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l255&quot;&gt;255번째 줄:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;255번째 줄:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==[[오토잇 폴더 내부 텍스트 | 참고- 오토잇 폴더 내부 텍스트]]==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Devcafe</name></author>
	</entry>
	<entry>
		<id>https://devcafe.co.kr/w/index.php?title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89&amp;diff=2317&amp;oldid=prev</id>
		<title>Devcafe: 새 문서: &lt;source lang=python&gt;  import os import re from pathlib import Path import argparse import sys from datetime import datetime  class TextFileSearcher:     def __init__(self):         # 기본 텍스트 파일 확장자         self.text_extensions = {&#039;.txt&#039;, &#039;.log&#039;, &#039;.sql&#039;, &#039;.py&#039;, &#039;.java&#039;, &#039;.js&#039;, &#039;.html&#039;,                                &#039;.xml&#039;, &#039;.json&#039;, &#039;.csv&#039;, &#039;.ini&#039;, &#039;.cfg&#039;, &#039;.conf&#039;,                                &#039;.properties&#039;, &#039;.yml&#039;, &#039;.yaml&#039;, &#039;.md&#039;, &#039;.bat&#039;, &#039;.sh&#039;}...</title>
		<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%ED%8C%8C%EC%9D%B4%EC%8D%AC_%ED%8F%B4%EB%8D%94_%EB%82%B4%EB%B6%80_%ED%85%8D%EC%8A%A4%ED%8A%B8_%EA%B2%80%EC%83%89&amp;diff=2317&amp;oldid=prev"/>
		<updated>2025-09-26T06:58:13Z</updated>

		<summary type="html">&lt;p&gt;새 문서: &amp;lt;source lang=python&amp;gt;  import os import re from pathlib import Path import argparse import sys from datetime import datetime  class TextFileSearcher:     def __init__(self):         # 기본 텍스트 파일 확장자         self.text_extensions = {&amp;#039;.txt&amp;#039;, &amp;#039;.log&amp;#039;, &amp;#039;.sql&amp;#039;, &amp;#039;.py&amp;#039;, &amp;#039;.java&amp;#039;, &amp;#039;.js&amp;#039;, &amp;#039;.html&amp;#039;,                                &amp;#039;.xml&amp;#039;, &amp;#039;.json&amp;#039;, &amp;#039;.csv&amp;#039;, &amp;#039;.ini&amp;#039;, &amp;#039;.cfg&amp;#039;, &amp;#039;.conf&amp;#039;,                                &amp;#039;.properties&amp;#039;, &amp;#039;.yml&amp;#039;, &amp;#039;.yaml&amp;#039;, &amp;#039;.md&amp;#039;, &amp;#039;.bat&amp;#039;, &amp;#039;.sh&amp;#039;}...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;새 문서&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import re&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
import argparse&lt;br /&gt;
import sys&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
&lt;br /&gt;
class TextFileSearcher:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        # 기본 텍스트 파일 확장자&lt;br /&gt;
        self.text_extensions = {&amp;#039;.txt&amp;#039;, &amp;#039;.log&amp;#039;, &amp;#039;.sql&amp;#039;, &amp;#039;.py&amp;#039;, &amp;#039;.java&amp;#039;, &amp;#039;.js&amp;#039;, &amp;#039;.html&amp;#039;, &lt;br /&gt;
                              &amp;#039;.xml&amp;#039;, &amp;#039;.json&amp;#039;, &amp;#039;.csv&amp;#039;, &amp;#039;.ini&amp;#039;, &amp;#039;.cfg&amp;#039;, &amp;#039;.conf&amp;#039;, &lt;br /&gt;
                              &amp;#039;.properties&amp;#039;, &amp;#039;.yml&amp;#039;, &amp;#039;.yaml&amp;#039;, &amp;#039;.md&amp;#039;, &amp;#039;.bat&amp;#039;, &amp;#039;.sh&amp;#039;}&lt;br /&gt;
        &lt;br /&gt;
    def search_files(self, root_path, search_text, case_sensitive=False, &lt;br /&gt;
                    use_regex=False, file_extensions=None, encoding=&amp;#039;utf-8&amp;#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        지정된 폴더와 하위 디렉토리에서 텍스트 파일 내용을 검색&lt;br /&gt;
        &lt;br /&gt;
        Args:&lt;br /&gt;
            root_path: 검색할 루트 폴더 경로&lt;br /&gt;
            search_text: 검색할 텍스트 또는 정규식&lt;br /&gt;
            case_sensitive: 대소문자 구분 여부&lt;br /&gt;
            use_regex: 정규식 사용 여부&lt;br /&gt;
            file_extensions: 검색할 파일 확장자 (None이면 기본 확장자 사용)&lt;br /&gt;
            encoding: 파일 인코딩&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        results = []&lt;br /&gt;
        root_path = Path(root_path)&lt;br /&gt;
        &lt;br /&gt;
        if not root_path.exists():&lt;br /&gt;
            print(f&amp;quot;경로가 존재하지 않습니다: {root_path}&amp;quot;)&lt;br /&gt;
            return results&lt;br /&gt;
        &lt;br /&gt;
        # 검색할 파일 확장자 설정&lt;br /&gt;
        extensions = file_extensions if file_extensions else self.text_extensions&lt;br /&gt;
        &lt;br /&gt;
        # 정규식 패턴 컴파일&lt;br /&gt;
        if use_regex:&lt;br /&gt;
            try:&lt;br /&gt;
                pattern = re.compile(search_text, 0 if case_sensitive else re.IGNORECASE)&lt;br /&gt;
            except re.error as e:&lt;br /&gt;
                print(f&amp;quot;정규식 오류: {e}&amp;quot;)&lt;br /&gt;
                return results&lt;br /&gt;
        else:&lt;br /&gt;
            if not case_sensitive:&lt;br /&gt;
                search_text = search_text.lower()&lt;br /&gt;
        &lt;br /&gt;
        print(f&amp;quot;검색 시작: {root_path}&amp;quot;)&lt;br /&gt;
        print(f&amp;quot;검색어: {search_text}&amp;quot;)&lt;br /&gt;
        print(f&amp;quot;정규식 사용: {use_regex}&amp;quot;)&lt;br /&gt;
        print(f&amp;quot;대소문자 구분: {case_sensitive}&amp;quot;)&lt;br /&gt;
        print(&amp;quot;-&amp;quot; * 50)&lt;br /&gt;
        &lt;br /&gt;
        file_count = 0&lt;br /&gt;
        match_count = 0&lt;br /&gt;
        &lt;br /&gt;
        # 모든 파일 재귀 탐색&lt;br /&gt;
        for file_path in root_path.rglob(&amp;#039;*&amp;#039;):&lt;br /&gt;
            if file_path.is_file() and file_path.suffix.lower() in extensions:&lt;br /&gt;
                file_count += 1&lt;br /&gt;
                &lt;br /&gt;
                try:&lt;br /&gt;
                    # 파일 내용 읽기 (여러 인코딩 시도)&lt;br /&gt;
                    content = self._read_file_with_encoding(file_path, encoding)&lt;br /&gt;
                    &lt;br /&gt;
                    if content is None:&lt;br /&gt;
                        continue&lt;br /&gt;
                    &lt;br /&gt;
                    # 검색 수행&lt;br /&gt;
                    matches = self._search_in_content(content, search_text, &lt;br /&gt;
                                                    case_sensitive, use_regex, pattern if use_regex else None)&lt;br /&gt;
                    &lt;br /&gt;
                    if matches:&lt;br /&gt;
                        match_count += 1&lt;br /&gt;
                        result = {&lt;br /&gt;
                            &amp;#039;file_path&amp;#039;: str(file_path),&lt;br /&gt;
                            &amp;#039;relative_path&amp;#039;: str(file_path.relative_to(root_path)),&lt;br /&gt;
                            &amp;#039;matches&amp;#039;: matches,&lt;br /&gt;
                            &amp;#039;file_size&amp;#039;: file_path.stat().st_size,&lt;br /&gt;
                            &amp;#039;modified_time&amp;#039;: datetime.fromtimestamp(file_path.stat().st_mtime)&lt;br /&gt;
                        }&lt;br /&gt;
                        results.append(result)&lt;br /&gt;
                        &lt;br /&gt;
                        # 실시간 결과 출력&lt;br /&gt;
                        print(f&amp;quot;✓ {result[&amp;#039;relative_path&amp;#039;]} ({len(matches)} 건)&amp;quot;)&lt;br /&gt;
                &lt;br /&gt;
                except Exception as e:&lt;br /&gt;
                    print(f&amp;quot;✗ 파일 읽기 오류 {file_path}: {e}&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        print(&amp;quot;-&amp;quot; * 50)&lt;br /&gt;
        print(f&amp;quot;검색 완료: {file_count}개 파일 중 {match_count}개 파일에서 발견&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        return results&lt;br /&gt;
    &lt;br /&gt;
    def _read_file_with_encoding(self, file_path, primary_encoding=&amp;#039;utf-8&amp;#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;다양한 인코딩으로 파일 읽기 시도&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        encodings = [primary_encoding, &amp;#039;utf-8&amp;#039;, &amp;#039;cp949&amp;#039;, &amp;#039;euc-kr&amp;#039;, &amp;#039;latin1&amp;#039;, &amp;#039;ascii&amp;#039;]&lt;br /&gt;
        &lt;br /&gt;
        for encoding in encodings:&lt;br /&gt;
            try:&lt;br /&gt;
                with open(file_path, &amp;#039;r&amp;#039;, encoding=encoding, errors=&amp;#039;ignore&amp;#039;) as f:&lt;br /&gt;
                    return f.read()&lt;br /&gt;
            except (UnicodeDecodeError, UnicodeError):&lt;br /&gt;
                continue&lt;br /&gt;
            except Exception:&lt;br /&gt;
                return None&lt;br /&gt;
        &lt;br /&gt;
        return None&lt;br /&gt;
    &lt;br /&gt;
    def _search_in_content(self, content, search_text, case_sensitive, use_regex, pattern):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;파일 내용에서 텍스트 검색&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        matches = []&lt;br /&gt;
        &lt;br /&gt;
        if use_regex:&lt;br /&gt;
            # 정규식 검색&lt;br /&gt;
            for match in pattern.finditer(content):&lt;br /&gt;
                line_num = content[:match.start()].count(&amp;#039;\n&amp;#039;) + 1&lt;br /&gt;
                line_content = content.split(&amp;#039;\n&amp;#039;)[line_num - 1].strip()&lt;br /&gt;
                matches.append({&lt;br /&gt;
                    &amp;#039;line_number&amp;#039;: line_num,&lt;br /&gt;
                    &amp;#039;line_content&amp;#039;: line_content,&lt;br /&gt;
                    &amp;#039;match_text&amp;#039;: match.group(),&lt;br /&gt;
                    &amp;#039;start_pos&amp;#039;: match.start(),&lt;br /&gt;
                    &amp;#039;end_pos&amp;#039;: match.end()&lt;br /&gt;
                })&lt;br /&gt;
        else:&lt;br /&gt;
            # 일반 텍스트 검색&lt;br /&gt;
            lines = content.split(&amp;#039;\n&amp;#039;)&lt;br /&gt;
            for i, line in enumerate(lines):&lt;br /&gt;
                search_line = line if case_sensitive else line.lower()&lt;br /&gt;
                if search_text in search_line:&lt;br /&gt;
                    matches.append({&lt;br /&gt;
                        &amp;#039;line_number&amp;#039;: i + 1,&lt;br /&gt;
                        &amp;#039;line_content&amp;#039;: line.strip(),&lt;br /&gt;
                        &amp;#039;match_text&amp;#039;: search_text&lt;br /&gt;
                    })&lt;br /&gt;
        &lt;br /&gt;
        return matches&lt;br /&gt;
    &lt;br /&gt;
    def print_detailed_results(self, results):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;상세 검색 결과 출력&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if not results:&lt;br /&gt;
            print(&amp;quot;검색 결과가 없습니다.&amp;quot;)&lt;br /&gt;
            return&lt;br /&gt;
        &lt;br /&gt;
        print(f&amp;quot;\n=== 상세 검색 결과 ({len(results)}개 파일) ===&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        for i, result in enumerate(results, 1):&lt;br /&gt;
            print(f&amp;quot;\n[{i}] {result[&amp;#039;relative_path&amp;#039;]}&amp;quot;)&lt;br /&gt;
            print(f&amp;quot;    크기: {result[&amp;#039;file_size&amp;#039;]:,} bytes&amp;quot;)&lt;br /&gt;
            print(f&amp;quot;    수정일: {result[&amp;#039;modified_time&amp;#039;].strftime(&amp;#039;%Y-%m-%d %H:%M:%S&amp;#039;)}&amp;quot;)&lt;br /&gt;
            print(f&amp;quot;    매치: {len(result[&amp;#039;matches&amp;#039;])}건&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
            for match in result[&amp;#039;matches&amp;#039;][:5]:  # 최대 5개만 표시&lt;br /&gt;
                print(f&amp;quot;      라인 {match[&amp;#039;line_number&amp;#039;]}: {match[&amp;#039;line_content&amp;#039;][:100]}&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
            if len(result[&amp;#039;matches&amp;#039;]) &amp;gt; 5:&lt;br /&gt;
                print(f&amp;quot;      ... 외 {len(result[&amp;#039;matches&amp;#039;]) - 5}건 더&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    def save_results(self, results, output_file):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;검색 결과를 파일로 저장&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        try:&lt;br /&gt;
            with open(output_file, &amp;#039;w&amp;#039;, encoding=&amp;#039;utf-8&amp;#039;) as f:&lt;br /&gt;
                f.write(f&amp;quot;텍스트 파일 검색 결과\n&amp;quot;)&lt;br /&gt;
                f.write(f&amp;quot;생성일시: {datetime.now().strftime(&amp;#039;%Y-%m-%d %H:%M:%S&amp;#039;)}\n&amp;quot;)&lt;br /&gt;
                f.write(f&amp;quot;총 {len(results)}개 파일에서 발견\n&amp;quot;)&lt;br /&gt;
                f.write(&amp;quot;=&amp;quot; * 80 + &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
                &lt;br /&gt;
                for i, result in enumerate(results, 1):&lt;br /&gt;
                    f.write(f&amp;quot;[{i}] {result[&amp;#039;file_path&amp;#039;]}\n&amp;quot;)&lt;br /&gt;
                    f.write(f&amp;quot;크기: {result[&amp;#039;file_size&amp;#039;]:,} bytes, &amp;quot;)&lt;br /&gt;
                    f.write(f&amp;quot;수정일: {result[&amp;#039;modified_time&amp;#039;].strftime(&amp;#039;%Y-%m-%d %H:%M:%S&amp;#039;)}\n&amp;quot;)&lt;br /&gt;
                    f.write(f&amp;quot;매치 건수: {len(result[&amp;#039;matches&amp;#039;])}\n&amp;quot;)&lt;br /&gt;
                    &lt;br /&gt;
                    for match in result[&amp;#039;matches&amp;#039;]:&lt;br /&gt;
                        f.write(f&amp;quot;  라인 {match[&amp;#039;line_number&amp;#039;]}: {match[&amp;#039;line_content&amp;#039;]}\n&amp;quot;)&lt;br /&gt;
                    &lt;br /&gt;
                    f.write(&amp;quot;\n&amp;quot; + &amp;quot;-&amp;quot; * 80 + &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
            print(f&amp;quot;결과가 저장되었습니다: {output_file}&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            print(f&amp;quot;파일 저장 오류: {e}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    parser = argparse.ArgumentParser(description=&amp;#039;폴더와 하위 디렉토리의 텍스트 파일에서 내용 검색&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;path&amp;#039;, help=&amp;#039;검색할 폴더 경로&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;search_text&amp;#039;, help=&amp;#039;검색할 텍스트&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;-i&amp;#039;, &amp;#039;--ignore-case&amp;#039;, action=&amp;#039;store_true&amp;#039;, help=&amp;#039;대소문자 무시&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;-r&amp;#039;, &amp;#039;--regex&amp;#039;, action=&amp;#039;store_true&amp;#039;, help=&amp;#039;정규식 사용&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;-e&amp;#039;, &amp;#039;--extensions&amp;#039;, help=&amp;#039;파일 확장자 (쉼표로 구분, 예: .txt,.log,.sql)&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;-o&amp;#039;, &amp;#039;--output&amp;#039;, help=&amp;#039;결과 저장할 파일명&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;--encoding&amp;#039;, default=&amp;#039;utf-8&amp;#039;, help=&amp;#039;파일 인코딩 (기본값: utf-8)&amp;#039;)&lt;br /&gt;
    parser.add_argument(&amp;#039;-d&amp;#039;, &amp;#039;--detail&amp;#039;, action=&amp;#039;store_true&amp;#039;, help=&amp;#039;상세 결과 출력&amp;#039;)&lt;br /&gt;
    &lt;br /&gt;
    args = parser.parse_args()&lt;br /&gt;
    &lt;br /&gt;
    # 파일 확장자 파싱&lt;br /&gt;
    extensions = None&lt;br /&gt;
    if args.extensions:&lt;br /&gt;
        extensions = set(ext.strip() for ext in args.extensions.split(&amp;#039;,&amp;#039;))&lt;br /&gt;
    &lt;br /&gt;
    # 검색 실행&lt;br /&gt;
    searcher = TextFileSearcher()&lt;br /&gt;
    results = searcher.search_files(&lt;br /&gt;
        root_path=args.path,&lt;br /&gt;
        search_text=args.search_text,&lt;br /&gt;
        case_sensitive=not args.ignore_case,&lt;br /&gt;
        use_regex=args.regex,&lt;br /&gt;
        file_extensions=extensions,&lt;br /&gt;
        encoding=args.encoding&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    # 결과 출력&lt;br /&gt;
    if args.detail:&lt;br /&gt;
        searcher.print_detailed_results(results)&lt;br /&gt;
    &lt;br /&gt;
    # 결과 저장&lt;br /&gt;
    if args.output:&lt;br /&gt;
        searcher.save_results(results, args.output)&lt;br /&gt;
&lt;br /&gt;
# 직접 실행할 때 사용하는 간단한 인터페이스&lt;br /&gt;
def simple_search():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;대화형 검색 인터페이스&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    print(&amp;quot;=== 텍스트 파일 검색 프로그램 ===&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    folder_path = input(&amp;quot;검색할 폴더 경로: &amp;quot;).strip()&lt;br /&gt;
    search_text = input(&amp;quot;검색할 텍스트: &amp;quot;).strip()&lt;br /&gt;
    &lt;br /&gt;
    use_regex = input(&amp;quot;정규식 사용하시겠습니까? (y/n): &amp;quot;).strip().lower() == &amp;#039;y&amp;#039;&lt;br /&gt;
    case_sensitive = input(&amp;quot;대소문자를 구분하시겠습니까? (y/n): &amp;quot;).strip().lower() == &amp;#039;y&amp;#039;&lt;br /&gt;
    &lt;br /&gt;
    searcher = TextFileSearcher()&lt;br /&gt;
    results = searcher.search_files(folder_path, search_text, case_sensitive, use_regex)&lt;br /&gt;
    &lt;br /&gt;
    if results:&lt;br /&gt;
        show_detail = input(&amp;quot;\n상세 결과를 보시겠습니까? (y/n): &amp;quot;).strip().lower() == &amp;#039;y&amp;#039;&lt;br /&gt;
        if show_detail:&lt;br /&gt;
            searcher.print_detailed_results(results)&lt;br /&gt;
        &lt;br /&gt;
        save_file = input(&amp;quot;결과를 파일로 저장하시겠습니까? (파일명 입력 또는 Enter): &amp;quot;).strip()&lt;br /&gt;
        if save_file:&lt;br /&gt;
            searcher.save_results(results, save_file)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # 명령행 인수가 있으면 CLI 모드, 없으면 대화형 모드&lt;br /&gt;
    if len(sys.argv) &amp;gt; 1:&lt;br /&gt;
        main()&lt;br /&gt;
    else:&lt;br /&gt;
        simple_search()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Devcafe</name></author>
	</entry>
</feed>