料理ブログ等のプロジェクトでClaude Codeを使い始めて、既存ファイルの一部だけ直したい人向け
料理ブログのすき焼き記事のタイトルだけを「家庭で作る本格すき焼き」に直したい時、材料の牛肉200gを300gに直したい時、frontmatterのタグを1つ足したい時など、既存ファイルの一部だけをピンポイントで修正したい場面で呼ばれる。複数ヶ所を一気に直したい時はMultiEdit、新規ファイル作成や全文書き直しはWriteに切り替える。
噛み砕くと
原稿用紙に書いた文章のうち、1行だけ消しゴムで消して書き直す作業のイメージです。他の段落、他のページ、表紙には一切触らない。Editは、その「狙ったところだけピンポイントで書き換える」をClaudeに頼むためのツール。
Writeとよく混同されます。
Writeはファイルをまるごと新しく書き直す。雑に言うと、原稿用紙を破り捨てて新しい紙に1から全部書き直す動きです。中身が10ページあっても、Writeで全部の中身を渡し直さないと既存の9ページが消えます。Editは違う。「3ページ目のこの一文」だけ書き換えるので、残りの9ページは安全です。
料理ブログなら、すき焼き記事の本文1500字のうち、タイトル1行だけ修正したい時。Writeで全文を書き直してClaudeに渡すと、本文の他の部分が無関係に書き換わるリスクがあります。Editなら、書き換え前のタイトル1行と書き換え後のタイトル1行だけを渡せば、本文には触れません。
Edit を呼ぶと画面に何が出るのか
料理ブログの content/recipes/sukiyaki.md のタイトル行を「すき焼きの作り方」から「家庭で作る本格すき焼き」に変えたい時、Claudeはこういう動きをします。
● Edit(content/recipes/sukiyaki.md)
⎿ Updated content/recipes/sukiyaki.md with 1 addition and 1 removal
1 - # すき焼きの作り方
1 + # 家庭で作る本格すき焼き
2
3 こんにちは。今日はすき焼きを作ります。
「Edit(ファイルパス)」が呼んだツール名と対象ファイル。⎿ の中が結果で、- 行が消えた行、+ 行が新しく入った行です。タイトル1行だけが入れ替わって、その下の本文「こんにちは。今日はすき焼きを作ります。」は触られていない、と一目で分かります。
初回は確認画面が挟まります。
Claude wants to edit content/recipes/sukiyaki.md:
- # すき焼きの作り方
+ # 家庭で作る本格すき焼き
[1] Yes
[2] Yes, allow all edits during this session
[3] No, tell Claude what to do differently
1で1回だけ承認、2でこのセッション中の全Editを通す、3で却下。3を選んだ時は「タイトルじゃなくて見出し2にして」みたいに別の指示を出し直せます。
料理ブログで「すき焼きレシピのタイトルだけ直す」再現手順
すき焼きレシピのタイトルを「すき焼きの作り方」から「家庭で作る本格すき焼き」に変えたい。本文・材料リスト・写真URLには触りたくない。この一連の流れを再現してみます。
ステップ1: Read で対象ファイルの中身を確認する
料理ブログのフォルダでClaude Codeを起動して、まずこう頼みます。
> content/recipes/sukiyaki.md の中身見せて
ClaudeはReadでファイルを開いて、行番号付きで返してきます。
● Read(content/recipes/sukiyaki.md)
⎿ Read 42 lines
1 # すき焼きの作り方
2
3 こんにちは。今日はすき焼きを作ります。
4
5 ## 材料(4人分)
6 - 牛肉 200g
...
このReadが必須です。Read を通さずにいきなりEditを頼むと、Claudeは「先にファイルを読まないと書き換えられない」と返してきて止まります。理由は次のh2で詳しく書きます。
ステップ2: 修正したい1ヶ所を特定して、Editを頼む
1行目のタイトルだけを直したいので、こう頼みます。
> sukiyaki.md のタイトルを「家庭で作る本格すき焼き」に変えて
Claudeが内部で次の3つの指定を組み立てます。
- file_path:
/home/aisola/projects/cooking-blog/content/recipes/sukiyaki.md(絶対パス) - old_string:
# すき焼きの作り方(書き換え前) - new_string:
# 家庭で作る本格すき焼き(書き換え後)
old_string と new_string、この2つだけがEditの主役。「ここに居る文字列を、こっちに置き換える」という単純な指定です。
ステップ3: 結果の差分を確認する
Edit実行後、Claudeはこう返してきます。
● Edit(content/recipes/sukiyaki.md)
⎿ Updated content/recipes/sukiyaki.md with 1 addition and 1 removal
1 - # すき焼きの作り方
1 + # 家庭で作る本格すき焼き
「1 addition and 1 removal」で、消えた行と追加された行が1ずつ。この時点でファイルの実体が書き換わっています。本文や材料リストには - も + も付いていないので、触られていません。
ここがEditの安全弁です。
差分でしか動かないので、意図しない部分の変更は応答に必ず出ます。応答に変な行が混ざっていたら即気づけます。
ステップ4: 同じファイルに複数の修正を入れたい時はMultiEditに切り替え
もしタイトルだけじゃなく「材料の牛肉200gを300gに」「最後の段落の『お楽しみください』を『召し上がれ』に」と3ヶ所まとめて直したい時。Editを3回連続で呼ぶ手もありますが、Claude Codeには専用のMultiEditツールがあります。
● MultiEdit(content/recipes/sukiyaki.md)
⎿ Applied 3 edits:
1 - # すき焼きの作り方
1 + # 家庭で作る本格すき焼き
6 - - 牛肉 200g
6 + - 牛肉 300g
40 - お楽しみください
40 + 召し上がれ
1回の呼び出しで3ヶ所まとめて差し替えます。1ヶ所目で失敗したら全部巻き戻る作りなので、中途半端な状態になりません。1ヶ所だけならEdit、複数ならMultiEdit、と覚えておけば足ります。
Read を先に呼ばないと Edit は失敗する──公式が定めたルール
これは知らないと最初に必ずハマる仕様です。Editは、対象ファイルが「同じセッションでReadされている」前提でしか動きません。Readされていないファイルへの編集を頼むと、Claudeは即こう返します。
Error: File has not been read yet. Read it first before writing to it.
「先に読め」と叱られて、Edit自体が走りません。
なぜか。Editは old_string と new_string の差分だけを受け取って動きます。ファイル全体を見ていない状態で「この文字列を書き換える」を実行すると、似た文字列が他にもあった時に意図しない場所が書き換わります。先にRead で全文を読んでおけば、old_string が他にも出てくるかどうかをClaude側で判定できる。だから Read 必須、という設計です。
実用上、Claudeは賢いので「Editしたい」と言えば、Read してないファイルなら自動でReadを先に挟みます。私が手で「先にReadして」と頼まなくても、内部で順番に呼んでくれます。なのでこのエラーを直接見るのは、Read を消した直後に Edit を頼んだ時とか、別セッションで Read だけ済んだファイルを引きずろうとした時くらいです。
セッションを /clear でリセットした直後にいきなりEditを頼むと、このエラーに当たることがあります。/clear 後は会話履歴と一緒にRead済みファイルの記録も消えるためです。
old_string が一意じゃないとFAIL──新人がよくハマる落とし穴
もう1つの定番の罠です。Editは old_string が「ファイル内で1ヶ所しか登場しない」前提で動きます。同じ文字列が2ヶ所3ヶ所あると、Claudeは「どれを書き換えればいいか分からない」と判断してこう返します。
Error: old_string appears 3 times in the file. Provide a more unique old_string with surrounding context, or set replace_all: true.
料理ブログで考えると分かりやすい。すき焼きレシピの中に - 醤油 大さじ2 という行が、材料リストと割り下のレシピの両方に出てくる。「醤油を大さじ3に変えて」と頼むと、どっちの醤油か特定できないのでEditが止まります。
解決策は2つあります。
- 周辺の行を含めて長くする。
- 醤油 大さじ2単体ではなく、その上の### 材料から下の- 砂糖 大さじ1までを丸ごと old_string に入れる。これで一意になります。Claudeは賢いので「材料側の醤油を変えて」と頼めば自動で周辺コンテキストを取って組み立ててくれます - 両方とも変えていいなら replace_all を true にする。「材料も割り下も両方とも醤油を大さじ3にして」という意図なら、replace_all: true を指定すれば3ヶ所全部一気に置換されます。リファクタリングで変数名を全置換する時にもこれを使います
新人がやりがちなのは「醤油を大さじ3に」とだけ頼んで、最初に出てきた1つだけが書き換わる、を期待するパターン。Editは「最初の1つだけ」では動かないので、必ずFAILになるか、replace_all で全部置換される、のどっちかです。
Write/MultiEdit との使い分け──料理ブログでの判断ライン
3つとも「ファイルを書き換える」ツールですが、用途が完全に分かれます。
- Edit: 既存ファイルの「1ヶ所だけ」を書き換える。すき焼き記事のタイトルだけ直す、材料の分量1ヶ所だけ直す、frontmatterのタグを1つ追加する、みたいな小さな修正
- MultiEdit: 既存ファイルの「複数ヶ所」をまとめて書き換える。タイトル+材料3ヶ所+本文の言い回し2ヶ所、を1回で。Editを連発する代わり
- Write: ファイルを「丸ごと新規作成」または「完全に書き直す」。新しいおでんレシピ記事を作る、または既存記事を全文リライトする時
判断ラインは単純です。
- 新しいファイルを作る → Write一択(Editは新規作成不可)
- 既存ファイルの一部だけ直す → Edit(1ヶ所)または MultiEdit(複数ヶ所)
- 既存ファイルを全部書き直す → Write
料理ブログの実務だと、新規レシピ追加はWrite、誤字直し・分量の調整・タグ追加はEdit、リライトはWrite、という棲み分けに自然と落ち着きます。
Bashの sed -i で代用するのは避けたほうがいい。sed -i 's/200g/300g/' sukiyaki.md と打つと、ファイル内の「200g」が全部書き換わるか、シェルの解釈ミスで失敗するかのどちらかで、応答にも何が変わったか出ない。Editなら差分が応答に必ず出るので、後追いで「何を変えたか」が見直せます。
料理ブログでの使いどころ
シナリオ1: タイトルや見出しの言い回しだけ整える
すき焼き記事のタイトルを「すき焼きの作り方」から「家庭で作る本格すき焼き」に直す、h2見出しの「材料」を「材料(4人分)」に直す、みたいな1行だけの修正。本文に手を入れたくない時、Editがそのまま当たります。タイトル変更は記事内で1ヶ所しか出ないので、old_string の一意性も自動で満たされやすい。
シナリオ2: 材料の分量を1ヶ所だけ調整する
「牛肉200gだと2人分にちょうどいいけど、4人分のレシピだから300gに」みたいな分量変更。- 牛肉 200g という行は記事内で1ヶ所しか出ないので、Editで一発です。割り下にも醤油があって、材料側の醤油だけ変えたい場合は、周辺の ### 材料 見出しを含めた範囲をold_stringにすれば一意化できます。
シナリオ3: frontmatterのタグやカテゴリを足す
記事冒頭の tags: ["和食"] に「鍋料理」を足したい時。Editで tags: ["和食"] を tags: ["和食", "鍋料理"] に置き換えるだけ。frontmatterは記事の最初の数行に固まっていて、本文の中の文字列とは混ざらないので、一意性も自然と確保されます。
初心者が踏みやすい落とし穴
- Read を挟まずにいきなりEditを頼んで止まる。Claudeは賢いので普通は自動でReadを先に挟みますが、
/clearでセッションを白紙にした直後とか、別エージェントから渡された情報だけで動かそうとした時に、Read 漏れでエラーが出ます。詰まったら「まず該当ファイルをReadで開いて」と一言挟むだけで動きます - old_string に行番号プレフィックスを含めてしまう。Read の出力に付いてくる
1\t# すき焼きの作り方の1\t(行番号+タブ)を、そのまま old_string に入れるとFAILします。実ファイルにはこの行番号は書かれていないためです。プレフィックスより後の中身だけを使います。Claudeは内部でこれを正しく処理しますが、私が old_string を手で組み立ててClaudeに渡す時は注意が要る - old_string が一意じゃなくてFAIL。同じ文字列が複数ヶ所にある時の典型エラー。「どっちを変えるか分かりません」と止まるので、周辺の行を含めて長くするか、両方変えていいなら replace_all を true にして再依頼。「醤油を大さじ3に」とだけ頼んで「最初の1つだけ書き換わる」を期待しない
- Editで新しいファイルを作ろうとして失敗。Editはあくまで「既存ファイルの一部書き換え」用。
content/recipes/oden.mdがまだ無い状態でEditを頼むと「ファイルが無い」と返ります。新規作成はWriteの仕事 - インデント(先頭のスペース・タブ)の扱いを間違える. YAMLのfrontmatterや、Markdownのリストのインデントは old_string と new_string で完全に一致させないとFAILします。「
- 牛肉 200g」のようにスペース2個でインデントされているなら、書き換え後の- 牛肉 300gも同じスペース2個で書く必要がある。インデントが崩れるとパーサーが壊れて、ビルドエラーに繋がる - 大きな範囲をEditで頼みすぎる。30行越えの差し替えになったら、もうそれはEditではなくWriteかMultiEditの仕事。old_string が長くなりすぎると、空白・改行のわずかな違いでマッチしなくなる確率が跳ね上がります。「中身まるごと書き直し」ならWriteが素直
- Edit前にgit commitを忘れる。Editは差分が応答に出るので追跡しやすいとはいえ、複数のEditを連続で当てた後に「やっぱり全部戻したい」と思った時、commitしてないと巻き戻せない。料理ブログでまとまった編集を始める前に、Bashで
git statusとgit commitを1回挟んでおくと、いざという時にgit checkout .で全部戻せます
関連するコマンド・ツールへの動線
- Read(リード) - ファイルの中身をClaudeに見せるツール。Editを呼ぶ前に必ずこれが先に走る。Read無しでEditは動かない
- Write(ライト) - ファイルを新規作成・全置換するツール。Editは既存の一部書き換え専用、新規作成や全文リライトはこちら
- Bash(バッシュ) - シェルコマンドを叩くツール。
sed -iでファイル置換するよりEditのほうが安全で追跡しやすい - /init(イニット) - プロジェクト用の覚え書き
CLAUDE.mdの雛形を半自動で作るスラッシュコマンド。料理ブログを始めた初日に1回叩く - /memory(メモリー) -
CLAUDE.mdを直接開いて手で編集するスラッシュコマンド。覚え書きへの追記もEditで行われる - CLAUDE.md(クロードドットエムディー) - プロジェクト用の覚え書きファイル本体。「既存ファイルの編集はEdit優先、新規作成のみWrite」のような運用ルールをここに書いておくと、Claudeが従ってくれる
- /agents(エージェンツ) - 専門エージェントの管理画面を開くスラッシュコマンド。エージェントごとにEdit使用の可否を細かく分けられる
- /clear(クリア) - 会話履歴をリセットするスラッシュコマンド。
/clear後はRead済みファイルの記録も消えるので、再度Readからやり直し - /compact(コンパクト) - 会話履歴を要約して圧縮するスラッシュコマンド。Editを多数当てた後にログが膨らんだ時に呼ぶ
- Skills(スキルズ) - 再利用できる作業手順をまとめておく仕組み。スキル内で「特定パターンで Edit を当てる」手順を定型化できる
- Hooks(フックス) - ツール実行の前後に処理を差し込む仕組み。Editの前後に検閲を入れる PreToolUse / PostToolUse フックがよく使われる
- MCP(エムシーピー) - Claude Codeに外部ツールを足す仕組み。専用エディタ系MCPツールを足してEditの代替にする選択肢になる
参考リンク
書き方
Claudeが内部で3つの値を組み立ててEditツールに渡す。file_path(書き換え対象ファイルの絶対パス)、old_string(書き換え前の文字列)、new_string(書き換え後の文字列)。同じ文字列が複数ヶ所にある時に全部まとめて置換したい場合は replace_all: true を追加する。ユーザーが直接叩く形ではなく、自然文(「タイトルを家庭で作る本格すき焼きに変えて」など)で頼んだ結果としてEditが呼ばれる。
やってみるとこうなる
入力
> sukiyaki.md のタイトルを「家庭で作る本格すき焼き」に変えて
(Claudeが内部で file_path / old_string / new_string を組み立ててEditに渡す)
出力例
● Edit(content/recipes/sukiyaki.md)
⎿ Updated content/recipes/sukiyaki.md with 1 addition and 1 removal
1 - # すき焼きの作り方
1 + # 家庭で作る本格すき焼き
このページに出てきた言葉
- 差分
- 書き換え前と書き換え後で「どこがどう変わったか」だけを抜き出した表示。Editは <code>-</code> 行(消えた行)と <code>+</code> 行(新しく入った行)の差分形式で結果を返す
- 絶対パス
- ファイルの場所を「ルート(/)からの全ルート」で書いた表記。例: <code>/home/aisola/projects/cooking-blog/content/recipes/sukiyaki.md</code>。Editのfile_pathは絶対パスで指定する
- 相対パス
- いま居るフォルダを基準にしたファイルの場所の書き方。例: <code>content/recipes/sukiyaki.md</code>。表示用に短く書く時はこちらだが、Editに渡す内部の指定は絶対パス
- MultiEdit
- 同じファイルに複数の書き換えを一気に適用する専用ツール。Editを連続で呼ぶ代わりに使う。1ヶ所でも失敗すれば全部巻き戻るので、中途半端な状態を残さない
- replace_all
- 「ファイル内の同じ文字列を全部まとめて置換する」モードを有効にする指定。デフォルトはfalse(一意な1ヶ所だけ)。trueにすると同じ文字列が何ヶ所あっても全部書き換わる
- 行番号プレフィックス
- Read の出力に付いてくる「行番号+タブ」のこと。<code>1\t# すき焼きの作り方</code> の <code>1\t</code> の部分。Editの old_string にはこのプレフィックスを含めない(実ファイルにはこの行番号は書かれていないため)
- frontmatter
- Markdown記事の冒頭に書く設定ブロック(<code>---</code> で挟まれた部分)。タイトル・公開日・タグ等が入る。料理ブログでは <code>title: "すき焼き"</code> や <code>tags: ["和食"]</code> の編集にEditがよく効く
- セッション
- Claude Codeを起動してから終了するまでの1単位。セッション中は会話履歴とRead済みファイルが共有されている。<code>/clear</code> でリセットすると、Read済みの記録も一緒に消える
- Hugo
- 静的サイトジェネレーター(テンプレートと記事ファイルからHTMLサイトを生成するツール)の1つ。料理ブログのような記事中心のサイトでよく使われる
- kebab-case
- 単語をハイフンで繋いだ命名規則。<code>recipe-list</code> <code>main-dish</code> のような形。frontmatterのslug等で使う