---
title: "@힣: #이맥스 #검색 #일괄편집 #워크플로우 #한번에 #전체 #점진 #변경 #치환 #정규식"
url: "https://notes.junghanacs.com/notes/20230710T191400"
author: "Junghan Kim"
date: "2023-07-10T19:14:00+09:00"
lastmod: "2026-02-19T00:00:00+09:00"
tags: ["autholog","bib","doomemacs","editing","emacs","isearch","regex","ripgrep","vertico"]
description: "이맥스에서 검색, 정규식, 일괄 치환, wgrep 편집을 한 흐름으로 엮어 보는 작업 철학의 기록."
---

> [!abstract] 이 노트에 대하여
> 
> 이맥스 안에서 검색과 편집, 정규식 치환, 일괄 변경을 하나의 워크플로우로 묶어 본다. 패키지 이름을 나열하는 수준을 넘어, 왜 텍스트 환경 전체가 점진적 변경에 유리한지까지 사유한 역사 노트다.

## 히스토리

-   [2026-02-19 Thu 12:30] 이게 왜 어쏠로그인가? 이 주제는 매우 까다롭다. 이맥스에서 제공하는 옵션이 너무 많아서. 종합하는 역사 노트로서 발굴된 것!
    ```markdown
    ● 이미 타이틀도 @힣: 포맷으로 정리되어 있네요. 완벽합니다.
    
    ★ Insight ─────────────────────────────────────
    Denote 파일명 전략이 잘 드러나는 사례:
    ​- 타이틀(한글) = 인간의 검색용 — "검색", "치환",
    "한번에" 등 동의어/유사어를 넉넉히
    ​- 태그(영어) = 에이전트/프로그래밍 검색용 — consult,
    ripgrep, wgrep 등 정확한 패키지명
    ​- autholog 태그 하나로 발행 파이프라인 진입 표시
    ─────────────────────────────────────────────────
    
    2023년 5월 첫 wgrep 발견 → 2026년 2월 consult-ripgrep
    문법 파악. 2년 반 숙성된 에버그린 노트가 탄생했습니다.
    ```
-   [2026-02-19 Thu 12:23] 종합 - 에이전트와 업데이트
    
    -   2023년 7월 첫 삽질(wgrep 발견)부터 2026년 2월
    
    consult-ripgrep 문법 파악까지, 2년 반의 점진적 이해가 하나의 노트에 담겼습니다.
    
    -   디지털 가든의 핵심이 이것 — 시간이 지나며 노트가 성숙해가는 과정. Evergreen note.
-   [2023-08-21 Mon 13:18] 2023-08-21 incremental search and replace 방법은 어떤가?
-   [2023-07-10 Mon 19:14] 2023-07-10 `rg` Usages : ripgrep and wgrep
-   [2023-05-03 Wed 14:02] 2023-05-03 Edit and apply (wgrep)

## 관련메타

-   [†#둠이맥스 #스페이스맥스](https://notes.junghanacs.com/meta/20241003T171723)
-   [† #일괄편집 #증분검색 #점진적검색 (메타)](https://notes.junghanacs.com/meta/20240901T122732)

## 관련노트

-   [#일괄편집 rg-menu 텍스트 파일 검색 변경 (2023-09-07)](https://notes.junghanacs.com/notes/20230907T190500)
-   [#정규표현식: 정규식 검색 일부 텍스트 변경](https://notes.junghanacs.com/notes/20240915T234215)

## 2026-02-19 †# 이런 케이스를 처리하려면?

[2026-03-14 Sat 02:23]

@user 아래 관련 내용을 알려줄게. 근데 내가 지금 †# 이렇게 붙어있는 케이스를 찾아서 검색해보려고하거든. 이런 케이스는 어떻게 처리하지? 아래 정리한 내용봐서는 커버가 안되네.

````markdown

## `†#` 케이스 검색 방법

### 문제 분석

`†#` 에서 두 문자 모두 특수문자라 이중으로 처리가 필요하다:

- `†` (U+2020) — 유니코드 특수문자, ripgrep은 기본 처리 가능
- `#` — *consult의 구분자(separator)* 로 해석되어 패턴이 끊김

즉 `#†#` 입력 시 → consult가 `†`를 패턴, 두 번째 `#` 이후를 플래그로 파싱해버림.

---

### 해결법: 구분자를 바꾼다

consult는 구분자를 *첫 입력 문자*로 동적 결정한다.
`#` 대신 다른 문자를 구분자로 쓰면 된다.

```
/†#        ← / 를 구분자로 사용
%†#        ← % 를 구분자로 사용
```

규칙: *패턴에 포함되지 않는 문자*를 맨 앞에 놓으면 그게 구분자가 된다.

---

### `-F` (fixed-strings) 병용 권장

`†#`은 정규식 메타문자가 아니지만, 리터럴 검색임을 명시하면 안전하다:

```
/†##-F
```

분해:
| 위치 | 내용 | 의미 |
|------|------|------|
| `/` | 구분자 | consult separator |
| `†#` | 패턴 | 실제 검색어 |
| `/` | 구분자 반복 | 플래그 영역 시작 |
| `-F` | ripgrep 플래그 | 리터럴 검색 |

---

### 정리: 구분자 선택 기준

| 상황 | 추천 구분자 |
|------|------------|
| 패턴에 `#` 포함 | `/` `%` `!` 등 |
| 패턴에 `/` 도 포함 | `%` `!` `@` 등 |
| 안전한 범용 | `%` (코드에 드물게 등장) |

````

## 2026-02-19 Doom Emacs consult-ripgrep 검색 입력법

[2026-02-19 Thu]

Doom Emacs에서 `SPC s p` (project search)를 쓰면서 정작 입력 문법을 모르고 있었다. 소문자 `bd-` 를 검색하는데 대문자 `BD` 까지 잡히고, 하이픈 `-` 이 먹히지 않는 문제를 겪고 나서야 내부 구조를 파악하게 되었다.

### 검색 체인: SPC s p → consult-ripgrep

````text
SPC s p
  → +vertico-file-search  (doom/modules/completion/vertico/autoload/vertico.el)
    → consult-ripgrep
      → rg (ripgrep)
````

Doom이 ripgrep 인자를 직접 조립한다. 핵심 플래그:

````sh
rg --smart-case --no-heading --with-filename --line-number --search-zip --hidden -g !.git
````

### --smart-case 함정

`--smart-case` 는 ripgrep의 기본 동작으로:

-   **소문자만 입력** → case-insensitive (대소문자 무시)
-   **대문자가 하나라도 포함** → case-sensitive (정확 매치)

따라서 `bd-` 를 검색하면 `BD-`, `Bd-` 도 잡힌다. 이건 버그가 아니라 의도된 동작.

### consult async split 구문 (perl 스타일)

consult-ripgrep은 비동기 검색이라 **구분자(separator)** 가 필요하다. 기본 구분자는 `#`.

````text
#패턴          ← 기본 검색
#패턴#플래그   ← ripgrep 플래그 전달 (두 번째 # 이후)
````

#### 실전 입력 예시

| 입력               | 의미                                    |
|------------------|---------------------------------------|
| `#bd-`             | `bd-` 검색 (case-insensitive, smart-case) |
| `#bd-# -s`         | `bd-` 검색 (case-sensitive 강제)        |
| `#TODO# -g *.org`  | `.org` 파일에서만 `TODO` 검색           |
| `#defun# -t elisp` | elisp 파일 타입에서 `defun` 검색        |
| `#패턴# -w`        | 단어 단위 매치 (word boundary)          |

#### 자주 쓰는 ripgrep 플래그

| 플래그                    | 의미                        |
|------------------------|---------------------------|
| `-s` / `--case-sensitive` | 대소문자 구분 강제          |
| `-w` / `--word-regexp`    | 단어 경계 매치              |
| `-g *.ext`                | 특정 확장자만               |
| `-t type`                 | 파일 타입 (elisp, python, js 등) |
| `-F` / `--fixed-strings`  | 정규식 아닌 리터럴 검색     |

### 전체 워크플로우: 검색 → 일괄편집

````text
1. SPC s p        → consult-ripgrep 검색 (#패턴#플래그)
2. M-o E          → embark-export (결과를 grep 버퍼로 내보내기)
3. C-c C-p        → wgrep-mode 진입 (편집 가능 상태)
4. 편집            → evil 매크로, :%s, 수동 편집 등
5. C-c C-c        → 변경사항 모든 파일에 적용
   (또는 Z Z)
6. C-c C-k        → 변경 취소
````

이 흐름이 Doom Emacs에서 프로젝트 전체를 대상으로 검색→일괄편집하는 정석이다. `rg.el` 의 `C-c C-p` 워크플로우와 동일한 개념이지만, consult/vertico/embark 스택 위에서 동작한다.

### isearch (C-s) 와의 차이

|            | `C-s` (isearch) | `SPC s p` (consult-ripgrep)    |
|------------|-----------------|--------------------------------|
| 범위       | 현재 버퍼       | 프로젝트 전체                  |
| 백엔드     | Emacs 내장      | ripgrep (외부)                 |
| 대소문자   | `M-c` 토글      | `--smart-case` (기본), `#패턴# -s` |
| 하이픈 등 특수문자 | 리터럴          | 리터럴 (consult 구분자 `#` 만 주의) |
| 일괄편집   | 불가            | embark-export → wgrep          |

### evil search (/) 와의 차이

Evil의 `/` 검색은 현재 버퍼 내에서 동작하며, 정규식은 Emacs flavor를 사용한다. 프로젝트 전체 검색이 필요하면 반드시 `SPC s p` 를 쓴다.

## 2023-08-21 incremental search and replace 방법은 어떤가?

[2023-08-21 Mon 13:18]

아래 "Doom Emacs consult-ripgrep 검색 입력법" 섹션에서 정리.

## 2023-07-10 `rg` Usages : ripgrep and wgrep

[2023-07-10 Mon 19:14]

메뉴로 가서 따라 해본다. -h 입력하면 hidden 폴더 검색한다. .emacs.d 는 hidden 폴더니까 옵션 없으면 검색 안된다. .git 폴더는 기본 제외 된다. 옵션이 있다.

````text
-*- mode: rg; default-directory: "~/sync/man/dotsamples/vanilla/" -*-
rg started at Wed Apr 19 17:46:19

/usr/bin/rg --color=always --colors=match:fg:red --colors=path:fg:magenta --colors=line:fg:green --colors=column:none -n --column -i --hidden --heading --no-config --type=elisp -e ekg

File: ahyatt-dotfiles/.emacs.d/init.el
 430  30   (pretty-hydra-define hydra-ekg ()
 432  12      (("t" ekg-show-notes-for-today "today" :exit t)
 433  12       ("g" ekg-show-notes-with-tag "tag" :exit t)
 434  12       ("r" ekg-show-notes-latest-captured "latest" :exit t)
 435  12       ("b" ekg-embedding-show-similar-to-current-buffer "similar to buffer" :exit t)
 436  12       ("s" ekg-embedding-search "search" :exit t))
 438  12      (("c" ekg-capture)
 516  18       ("k" hydra-ekg/body "ekg" :exit t)
 828  14 (use-package ekg
 829  15   :straight '(ekg :type git :host github :repo "ahyatt/ekg")
 831  13   ("<f11>" 'ekg-capture)
 835   6     (ekg-capture-url (ash/get-current-url) (ash/get-current-title))))
1147  24   (tab-bar-rename-tab "ekg" 2)

rg finished (15 matches found) at Wed Apr 19 17:46:19
````

## 2023-05-03 Edit and apply (wgrep)

[2023-05-03 Wed 14:02] rg 로 검색한 다음에 수정을 어떻게 하는가?

그냥 `SPC /` 로 검색하고 `M-o E` embark-export 로 뽑아낸 다음에 `,` major 모드 보면 w 인가에 저장하는게 있을거다. 잘 된다.

`C-c C-p` wgrep-mode 로 바꿔주고나서 수정하고 `Z Z` 입력하면 적용된다. 엄청난 팁이다.

Edit and apply (wgrep)
: The results buffer supports inline editing via the wgrep package. This is setup automatically when rg is loaded. e (wgrep-change-to-wgrep-mode) Make the search results editable by enabling wgrep mode. When done press C-c C-c to commit your changes to the underlying files or C-c C-k to drop the changes.
