awkでawkを書くようなワンライナーの書き方

例えば、こういう場合を考える

find . | awk '/\.sql$/{ print $0}'
./src/sql/testenv.sql
./src/sql/testtab.sql

こういうときに、カレントより下にある、拡張子がsqlなファイルを、全部.sql.bakに変えるコマンドが得たいときはこうする

find . | awk '/\.sql$/{print "mv "$0 " "$0".bak"}'
mv ./src/sql/testenv.sql ./src/sql/testenv.sql.bak
mv ./src/sql/testtab.sql ./src/sql/testtab.sql.bak

実行したいときは、こうやる。

find . | awk '/\.sql$/{print "mv "$0 " "$0".bak"}' | sh
(何も表示されない)

後ろに、パイプでshに渡してやると、そのまま実行される。まぁ、これはよくやるのであまり悩むことは無い。
今日は、awkawkを書こうとして悩んだ。つまりこういうとき

find . | awk '/\.sql$/{ print $0}'
./src/sql/testenv.sql
./src/sql/testtab.sql

こういう場合に、こういう出力を得たい、という場合

find . | awk '/\.sql$/{ print "cat "$0" | awk /hoge/{print \""$0"\" $0}"}' 
cat ./src/sql/testenv.sql | awk /hoge/{print "./src/sql/testenv.sql" $0}
cat ./src/sql/testtab.sql | awk /hoge/{print "./src/sql/testtab.sql" $0}

このコマンドの出力で、シングルクォーテーションの出力方法に困った。最初、¥でエスケープすれば良いだろうと思ってこうやって失敗

find . | awk '/\.sql$/{ print "cat "$0" | awk \'/hoge/{print \""$0"\" $0}\'"}' 
> (コマンドが終わってない。つまりエスケープが効いていない)

さんざん悩んだ末に、ようやくたどり着いた答えはこれ

find . | awk '/\.sql$/{ printf("cat %s | awk %c/hoge/{print \"%s\" $0}%c\n",$0,39, $0,39)}' 
cat ./src/sql/testenv.sql | awk '/hoge/{print "./src/sql/testenv.sql" $0}'
cat ./src/sql/testtab.sql | awk '/hoge/{print "./src/sql/testtab.sql" $0}'

つまり。awkの中で、シングルクォーテーションを出したい場合は、39を%cで出せば良い。

echo "" | awk '{printf("%c",39)}'

ほんとうに、3時間ぐらい悩んだ。ちなみにダブルクォーテーションは\"で出せる、紛らわしい。でもやっぱり、メタプログラミングは楽しい。