コマンドラインのエスケープ

Windowsコマンドライン(cmd.exe)からPerlワンライナー書こうとして、「"」のエスケープがうまくできなくて困った。

sub quote_for_command {
  my $r = "";
  while (@_) {
    my $arg = shift;
    $arg =~ s/\%/^\%/gs;
    $arg =~ s/"/"""/gs;
    $r .= " " if $r ne "";
    $r .= "\"$arg\"";
  }
  return $r;
}

とか見ると、単純に「"""」で置き換えればよさげだけど、それだとうまくいかないようだ。どうも「"""」の後は、特殊記号のエスケープが効いてなさげ。

参考になりそうな資料のリストがあった。

コマンドラインエスケープ処理
http://jrf.cocolog-nifty.com/software/2006/02/post_19.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getcommandline.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/commandlinetoargv.asp
http://forums.belution.com/ja/vc/000/247/30s.shtml
http://techtips.belution.com/ja/vc/0084/
http://pc.2ch.net/tech/kako/1006/10067/1006783012.html 602〜

けど、めんどいから、[あとで読む]して、Perl内で対応することにする。

まず、単純な文字列の区切りとしてはqq()*1を使うとして、文字としての「"」はどうしようかと考えたら、

` と ( の xor を取って H を作るという知識は日常業務でも使えそうですね。

というのを思い出したので、これを使ってみる。
「"」は 0x22 *2 = 0b100010 *3 なので、これに近い値の文字を探すと、
0b100011 = 0x23 *4 = # *5
0b100110 = 0x26 *6 = & *7
ってことで、

print '&'&'#'

で「"」になる、と。*8


関係ないけど、perlでバイナリ表示してみた時のメモ。いろいろなんかあれだけど、まぁいいや。

perl -n -e "BEGIN{$l=0;}$l++;next if$l!=4;" -e "print; printf '%02X['.$_.'] ', ord for split//; print qq|\n|" "%00.htm"

"printf '%02X', ord for split//"がメイン。


あと、

9. パターンマッチは行全体ではなくフィールドで
perlだと、-aオプションを指定する事でawkっぽい振る舞いをさせることが出来ます。ただしフィールド変数は$数字ではなく、$F[数字]となります。

ls -l | perl -anle 'print if $F[6] eq "Dec"'

awkっぽいってのがなんかいやだったので、書き換えてみた。*9

dir | perl -ne "next if/^\D/; split; print $_[3].qq|\n| if $_[3] =~ /00/" | more

どうでもいいけど、2のtarのはperl使ってないじゃん、とか誰かつっこまないのかなぁ。
そういえば、昔大学のsoralisかなんかになんかのコマンドがインストールされてなくて、インストールの権限ないからインストールできないじゃん、代わりにperlスクリプトかなんかでないのかなぁ、そういえばunixの基本的なコマンドをperlで全部やっちゃうみたいな話をどっかで聞いたような、と思い出して探してみたけど、見つからなかった、というのを思い出した。*10

*1:Quote and Quote-like Operators

*2:http://www.google.co.jp/search?q=%22 ←%22になってる

*3:google:0x22を2進

*4:google:0b100011を16進

*5:http://www.google.co.jp/search?q=%23

*6:google:0b100110を16進

*7:http://www.google.co.jp/search?q=%26

*8:print char 0x22 でいいじゃん。

*9: [メモ] '-l'は改行を取る

*10:日本語でおk