Makefile関数チートシート:patsubst・wildcard・filter・foreachをコピペで使う

まずは、patsubst の使い方から。

SRCS = main.c util.c parser.c
OBJS = $(patsubst %.c,%.o,$(SRCS))

これで OBJSmain.o util.o parser.o になります。% がワイルドカードで、「.c で終わる各単語を、同じ名前の .o に置き換える」という意味です。この記事は patsubst を軸に、周辺でよく一緒に使う wildcard filter foreach までを逆引きでまとめたチートシートです。挙動はすべて手元の GNU Make で実行して確認しています(macOS標準の 3.81 と Homebrew の 4.4.1。関数の意味はこの範囲で違いはありませんでした)。

網羅的な仕様は GNU Make 4.4 日本語マニュアル 第8章「テキストを変換する関数」 にあります。この記事はその逆引き版です。

patsubst: パターン置換の基本

$(patsubst 検索パターン,置換パターン,対象の文字列) の3引数です。対象の文字列を空白で区切った単語ごとに、検索パターンにマッチしたものだけを置換パターンに差し替えます。

続きを読む Makefile関数チートシート:patsubst・wildcard・filter・foreachをコピペで使う

SQL の JOIN は省略できる — INNER/OUTER キーワードとカンマ結合の整理


JOIN とだけ書いたら INNER JOIN になるのか」「LEFT JOINLEFT OUTER JOIN は違うのか」という疑問への答えを先に書くと、どちらもまったく同じものです。INNEROUTER は書いても書かなくても意味の変わらないキーワードで、省略しても結果は 1 行も変わりません。

この記事では、省略形の対応表と「では実際どこまで省いて書くか」の指針、そして JOIN の省略とよく混同される「カンマ結合(FROM a, b)」がなぜ別物なのかを、実際に動かした結果つきで整理します。動作確認は 2026年7月に PostgreSQL 17.10 / MySQL 8.4.10 / SQLite 3.51.0 と Oracle Database Free(23ai系, 23.26.2.0.0)で行いました。JOIN そのものの種類と結果の違いは SQL の JOIN の種類と違いまとめ — INNER/LEFT/RIGHT/FULL/CROSS【2026年更新】 にまとめているので、そちらもどうぞ。

省略形の対応表

続きを読む SQL の JOIN は省略できる — INNER/OUTER キーワードとカンマ結合の整理

Oracle の JOIN の書き方 — 旧記法 (+) と ANSI 構文の対応表

古い Oracle のコードを読んでいると、FROM にテーブルをカンマで並べて WHERE で結合したり、WHERE a.id = b.id(+) のように (+) が付いていたりする SQL に出会います。これは Oracle が ANSI の JOIN 構文に対応する前から使われてきた旧記法で、(+) は Oracle 独自の外部結合演算子です。

結論から言うと、カンマ結合+WHERE は INNER JOIN、(+) は LEFT JOIN / RIGHT JOIN に対応します。この記事では実際の Oracle Database で両者の結果が一致することを確認しながら、書き換えの対応表と、書き換え時に踏みやすい Oracle 固有の癖をまとめます。なお、Oracle 公式マニュアルも新しく書くなら ANSI 構文を推奨しています(後述)。

実測環境は Docker の gvenzl/oracle-free:23-slim-faststart(バナー表記は Oracle AI Database 26ai Free Release 23.26.2.0.0)です。比較用の PostgreSQL 17.10 / MySQL 8.4.10 も Docker で動かしています。サンプルは次の2表です。

続きを読む Oracle の JOIN の書き方 — 旧記法 (+) と ANSI 構文の対応表

INNER JOIN と LEFT JOIN の違い — 結果がどう変わるか実例で確認

INNER JOIN と LEFT JOIN の違いは一言でいうと、相手のいない行を結果に残すかどうかです。INNER JOIN(内部結合)は両方のテーブルに対応する行があるものだけを返し、LEFT JOIN(左外部結合)は左のテーブルの行を全部残して、相手がいない行は右側の列を NULL で埋めます(これを NULL パディングと呼びます)。

この記事では同じデータに両方を実行して結果を見比べたあと、条件を ON に書くか WHERE に書くかで LEFT JOIN の結果が変わる罠と、「LEFT JOIN は遅いのか」という疑問を扱います。実行結果はすべて PostgreSQL 17.10 で実際に確認したもので、ON と WHERE の罠については MySQL 8.4.10 でも同じ結果になることを確認しています。JOIN 全種類のまとめは SQL の JOIN の種類と違いまとめ — INNER/LEFT/RIGHT/FULL/CROSS【2026年更新】 にあります。

サンプルデータ

社員表 emp と部署表 dept を使います。

続きを読む INNER JOIN と LEFT JOIN の違い — 結果がどう変わるか実例で確認

ImageMagick の xmp:validate とは何か。XMP検証エラーを回避する方法

ImageMagick で JPEG や PNG を処理していると、次のような警告に出会うことがあります。

identify: CorruptImageProfile `bad.jpg' (XMP) @ warning/profile.c/ValidateXMPProfile/2011.

これは画像に埋め込まれた XMP メタデータを ImageMagick が XML として読もうとして、壊れていると判断したときの警告です。画像のピクセル変換そのものが失敗しているとは限りません。

この記事では、壊れた XMP 入りの JPEG を手元で作って、xmp:validate を付けたときに何が起きるかを確認します。

xmp:validate は何をしているのか

xmp:validate は ImageMagick の -define で指定する設定です。

公式の defines ページでは、xmp:validate={true,false} は「画像に埋め込まれた XMP プロファイルを検証する」と説明されています。

XMP は、ざっくり言うと画像に入る XML 形式のメタデータです。撮影・編集ソフト・権利情報・説明文などが入ることがあります。ImageMagick 側では、XML delegate が有効なビルドだと、この XMP を XML として読めるか確認できます。

手元の ImageMagick 7.1.2-27 では、xmp:validate=true を明示したときに CorruptImageProfile ... (XMP) の警告を確認しました。公式説明には「デフォルトで検証」とありますが、少なくともこの環境では、素の identify や変換では警告が出ませんでした。バージョンやビルド設定で挙動が違う可能性があるので、まず自分の環境で確認するのがよいです。

確認環境は以下です。

Version: ImageMagick 7.1.2-27 Q16-HDRI aarch64 e4c2b403b:20260705 https://imagemagick.org
Features: Cipher DPC HDRI Modules
Delegates (built-in): bzlib freetype heic jng jpeg lcms ltdl lzma png tiff webp xml zlib zstd

壊れた XMP 入り JPEG を作る

まず、わざと XML として壊れた XMP ファイルを作ります。

printf '\xff\xfe\x00\x00not xml\n' > bad.xmp
magick -size 32x32 xc:white base.jpg

普通に -profile bad.xmp すると環境によっては追加時点で警告されるので、ここでは xmp:validate=false を付けて、壊れた XMP を持つ JPEG を作ります。

magick base.jpg -define xmp:validate=false -profile bad.xmp bad.jpg

XMP プロファイルが入っていることは identify -verbose で確認できます。

magick identify -verbose bad.jpg 2>/dev/null | grep -Ei 'profiles|profile-xmp'

出力:

  Profiles:
    Profile-xmp: 12 bytes

xmp:validate=true で警告を再現する

xmp:validate=true を付けて identify します。

magick identify -define xmp:validate=true bad.jpg
echo $?

手元ではこうなりました。

bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.001
identify: CorruptImageProfile `bad.jpg' (XMP) @ warning/profile.c/ValidateXMPProfile/2011.
0

ここで大事なのは、終了コードが 0 のままだったことです。つまり、少なくともこのケースでは「警告は出るが、コマンドとしては成功」です。スクリプトが stderr の文字列を見て失敗扱いしている場合は別ですが、終了コードだけを見る処理なら失敗にはなりません。

警告だけ消すなら -quiet

ログに警告を出したくないだけなら、-quiet で警告は消えました。

magick identify -quiet -define xmp:validate=true bad.jpg
echo $?

出力:

bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.001
0

ただし、これは警告を黙らせるだけです。壊れた XMP は画像内に残ります。

検証を止めるなら xmp:validate=false

XMP の検証自体を止めるなら、入力ファイルより前に -define xmp:validate=false を置きます。

magick identify -define xmp:validate=false bad.jpg
echo $?

出力:

bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.000
0

変換でも同じ考え方です。

magick -define xmp:validate=false bad.jpg out.png

-define は入力を読む前に効かせたいので、迷ったら入力ファイル名より前に置くのが安全です。

XMP を消すなら +profile xmp

壊れた XMP が不要なら、検証を止めて読み込み、そのあとで XMP プロファイルだけ削除します。

magick -define xmp:validate=false bad.jpg +profile xmp clean-no-xmp.jpg
echo $?

出力:

0

削除後のファイルを確認します。

magick identify -verbose clean-no-xmp.jpg 2>/dev/null | grep -Ei 'profiles|profile-xmp'

出力は空でした。さらに、削除後のファイルは xmp:validate=true で読んでも警告が出ません。

magick identify -define xmp:validate=true clean-no-xmp.jpg
echo $?

出力:

clean-no-xmp.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 165B 0.000u 0:00.000
0

すべてのメタデータを消してよいなら -strip

XMP だけでなく、EXIF や ICC などのプロファイル、コメント類も落としてよいなら -strip が使えます。

magick -define xmp:validate=false bad.jpg -strip clean-strip.jpg
echo $?

出力:

0

-strip は画像を軽くしたいときには便利ですが、色管理の ICC プロファイルや撮影情報も落ちます。Web用サムネイルなら問題ないことが多い一方、印刷・写真管理・権利情報を残したい用途では雑に使わない方がよいです。

どれを使うべきか

目的別に分けると、こうです。

目的コマンド例注意
警告をログに出したくないだけmagick identify -quiet -define xmp:validate=true bad.jpgXMP は残る
XMP 検証をスキップしたいmagick -define xmp:validate=false input.jpg output.png壊れた XMP を温存する場合がある
XMP だけ消したいmagick -define xmp:validate=false input.jpg +profile xmp output.jpgXMP 内の説明・権利情報も消える
全メタデータを消してよいmagick -define xmp:validate=false input.jpg -strip output.jpgEXIF/ICC/コメントも消える

Webアプリの画像変換で「ユーザー投稿画像を縮小して表示するだけ」なら、-define xmp:validate=false-strip の組み合わせで済むことが多いです。逆に、写真のメタデータや色プロファイルを大事にする処理では、-strip ではなく +profile xmp のように削除対象を絞った方が安全です。

さいごに

xmp:validate は、画像のピクセルではなく XMP メタデータの検証に関わる設定です。CorruptImageProfile ... (XMP) が出ても、まずは終了コード、出力ファイル、XMP が必要かどうかを分けて見た方がよいです。

今回の手元検証では、警告が出ても終了コードは 0-quiet は警告を隠すだけ、xmp:validate=false は検証を止める、+profile xmp-strip はメタデータを実際に削除する、という違いが確認できました。

関連:

Makefile変数チートシート:自動変数 $@ $< $^ と := = の違い

Makefileを書いていると、$@$< みたいな記号や、=:= の使い分けで手が止まりがちです。この記事は変数まわりだけを逆引きでまとめたチートシートです。挙動はすべて手元の GNU Make で実行して確認しています。

もっと踏み込んだ仕様は GNU Make 4.4 日本語マニュアル 第6章「変数の使い方」 を参照してください。この記事はその逆引き版です。

=:= の違い(ここだけは押さえる)

いちばん引っかかるのがこれです。

  • = … 遅延展開。右辺は使うときに評価される。
  • := … 即時展開。右辺はその行を読んだ時点で評価される。

次の Makefile で違いが出ます。

続きを読む Makefile変数チートシート:自動変数 $@ $< $^ と := = の違い

Makefileの条件分岐 ifeq / ifdef 完全ガイド

Makefile で「デバッグビルドのときだけフラグを足したい」「OS ごとにコマンドを変えたい」といった分岐をしたいとき使うのが ifeqifdef です。書き方に少しクセがあるので、実例つきでまとめました。挙動はすべて手元の GNU Make で実行して確認しています。

仕様の詳細は GNU Make 4.4 日本語マニュアル 第7章「Makefileの条件分岐」 を参照してください。この記事はその実例版です。

4つの条件ディレクティブ

ディレクティブ 分岐の条件
ifeq 2つの値が等しい
ifneq 2つの値が等しくない
ifdef 変数が定義されている(空でない)
ifndef 変数が定義されていない(空)

いずれも elseendif で閉じます。else は省略できますが endif は必須です。

ifeq: 値を比較して分岐

続きを読む Makefileの条件分岐 ifeq / ifdef 完全ガイド

rsync でファイル名が文字化けするときの対処(–iconv と macOS の NFD 問題)

Mac から Linux サーバへ rsync でファイルを送ったら、日本語ファイル名の濁点・半濁点が分離して「テ゛ータ」のようになった。検索やタブ補完でファイル名がヒットしない。同期し直すたびに全ファイルが再転送される。こうした症状は、文字コードそのものではなく Unicode の正規化形式(NFC/NFD)の違いが原因です。

続きを読む rsync でファイル名が文字化けするときの対処(–iconv と macOS の NFD 問題)

rsync の終了コード一覧と意味

cron で回している rsync が 0 以外の終了コードを返してきたとき、その番号が何を意味するのかを調べるためのリファレンスです。まず一覧を載せて、そのあとで実際によく遭遇するコードの読み方とスクリプトでの扱い方を説明します。

終了コードは直後に echo $? で確認できます。

$ rsync -a /path/to/src/ /path/to/dst/
$ echo $?
0

終了コード一覧(rsync 3.4.4 の man ページより)

続きを読む rsync の終了コード一覧と意味

WindowsでUDP通信・ポート確認をする方法(PowerShell/ncat)

「WindowsでUDP通信を試したいのに、telnetもTest-NetConnectionも使えない」。結論から言うと、Windows標準のtelnetクライアントもTest-NetConnectionもTCP専用で、UDPには使えません。UDPを送受信するには、PowerShellのUdpClientか、ncat(Nmapに含まれるnetcat互換ツール)を使います。

※動作環境について:このページのコマンドは Windows 11(build 26200)+ Windows PowerShell 5.1 で動作を確認しています(2026-07-09)。Windows 10 や PowerShell 7 でも、使っているのは共通の .NET(UdpClient)と NetTCPIP モジュール(Get-NetUDPEndpoint など)なので同じように動くはずですが、表示のこまかな差は環境によって出ることがあります。

結論:WindowsでUDPを試す方法

続きを読む WindowsでUDP通信・ポート確認をする方法(PowerShell/ncat)