スティーブ・ジョブズ氏に哀悼の意を表しながら・・・簡易ファイルリスト実行プログラムです

iPhone4Sを発表したその日に氏が亡くなるとは・・・。こういうのには妙に運命を感じてしまう人です。

私の場合はそれほどAppleやMacintoshに関連性があったわけではないですが、それでもiOS系のプログラムに携わっている身でもありますし、

こういう偉大な人には常に敬意を表するというのが私の流儀なので。ご冥福をお祈りいたします。

これからAppleがどの方向に向かうのか、氏も天国から見ていることと思います。

それは置いておいて。

あんまり「特定の名前のファイル名をとある引数としてコマンドを順次実行する」というシェルスクリプトみたいなものってないですよね。

まあ、バッチでfor文をまわしても似たようなことができますが、毎回バッチファイルを作らなければならないのと、ファイル名に関する処理が固定になるのがやっかいだな~と思っていたところです。

というわけで、簡単にC言語でプログラムを組んでみました。

文字列処理だけSTLを使っていますが、わかる人ならSTLを取り除いたり、これをWindowsのコマンドプロンプト版からLinuxのシェルコマンド用に変更できると思います。

使ってみるといろいろと便利だったりします。ちなみに作った目的がmp4boxをすべてのmp4ファイルに実行させる、というものだったりしますが。

このコマンドでそれを実行すると、たとえば

wcexe *.mp4 mp4box -raw 1 %file%

とコマンドラインで打ち込むと、そのディレクトリにあるすべてのmp4ファイルに対してmp4boxによるライン抽出命令がバッチ形式で発行される、というわけです。

これは特定の名前のファイルだけ拡張子を変更する、といったことまでできたりします。ちょっとしたバッチ処理ならこれを中継させるととても便利かもしれません。

まあ、たぶんLinuxではシェルスクリプトやそれに準ずるコマンドがあるような気がしますが・・・。

#include
#include
#include
#include
#include
#include
#ifdef _UNICODE
#define TEXT(s) L##s
typedef std::wstring string;
#else
#define TEXT(s) s
typedef std::string string;
#endif //_UNICODE
const TCHAR c_szFileRawNameReplace[] = TEXT(“%file%”);
const TCHAR c_szFileNameReplace[] = TEXT(“%fname%”);
const TCHAR c_szFileExtReplace[] = TEXT(“%fext%”);
void usage(void)
{
_tprintf(TEXT(“usage: wcexe [filename] [cmd] … \n”));
_tprintf(TEXT(“\n\n”));
_tprintf(TEXT(“filename : argument file name (with wild card)\n”));
_tprintf(TEXT(” cmd : execute command on command prompt\n”));
_tprintf(TEXT(” … : command arguments\n”));
_tprintf(TEXT(“replace %s to filename,%s to filename without file extension and %s to file extension.\n”),c_szFileRawNameReplace,c_szFileNameReplace,c_szFileExtReplace);
_tprintf(TEXT(“\n\n”));
_tprintf(TEXT(“wcexe *.ht* rename %s %s.html\n”),c_szFileRawNameReplace,c_szFileNameReplace);
_tprintf(TEXT(“\n”));
}
void argstr(string &str,const TCHAR *arg,const string &fname,const string &fext)
{
const TCHAR *p,*p1,*p2,*p3; size_t l1,l2,l3;
p = arg;
p1 = _tcsstr(arg,c_szFileRawNameReplace);
p2 = _tcsstr(arg,c_szFileNameReplace);
p3 = _tcsstr(arg,c_szFileExtReplace);
while(p1 != NULL || p2 != NULL || p3 != NULL){
l1 = p1 != NULL ? p1 – p : (size_t)-1;
l2 = p2 != NULL ? p2 – p : (size_t)-1;
l3 = p3 != NULL ? p3 – p : (size_t)-1;
if(l1 < l2 && l1 < l3){ str.append(p,p1); str.append(fname); if(!fext.empty()){ str.append(TEXT(".")); str.append(fext); } p = p1 + _tcslen(c_szFileRawNameReplace); p1 = _tcsstr(p,c_szFileRawNameReplace); } else if(l2 < l1 && l2 < l3){ str.append(p,p2); str.append(fname); p = p2 + _tcslen(c_szFileNameReplace); p2 = _tcsstr(p,c_szFileNameReplace); } else{ str.append(p,p3); str.append(fext); p = p3 + _tcslen(c_szFileExtReplace); p3 = _tcsstr(p,c_szFileExtReplace); } } str.append(p); } int _tmain(int argc,TCHAR **argv) { intptr_t handle; _tfinddata_t vfinddata; string cmdline,fname,fext,str; string::size_type n; int i; if(argc <= 2){ usage(); return 0; } handle = _tfindfirst(argv[1],&vfinddata); if(handle == -1){ _ftprintf(stderr,TEXT("error: not found file %s\n"),argv[1]); return 1; } do{ if(_tcscmp(vfinddata.name,TEXT(".")) != 0 && _tcscmp(vfinddata.name,TEXT("..")) != 0){ fname.assign(vfinddata.name); fext.clear(); n = fname.rfind(TEXT('.'),string::npos); if(n != string::npos){ fext.assign(fname.begin() + n + 1,fname.end()); fname.resize(n); } cmdline.clear(); for(i = 2;i < argc;i++){ str.clear(); argstr(str,argv[i],fname,fext); cmdline += str; cmdline.append(TEXT(" ")); } _tprintf(TEXT("execute : %s\n"),cmdline.c_str()); _tsystem(cmdline.c_str()); } if(_tfindnext(handle,&vfinddata) < 0){ _findclose(handle); handle = -1; } } while(handle != -1); return 0; } [/cpp]

なお、プログラム中の英文は適当です。英文を読めても書けないのが私の能力で悪いところですからね・・・。

あと、コマンド名はとりあえず適当ですが、簡易的に「wild card executer」の先頭文字を使って名付けていたりします。

プログラムソースとしては3kBと短いものになりました。

これを使ってみたい方は普通にVisual C++ 2010 Express Editionあたりを手に入れてコンパイルすれば終わりのはずです。

本体ファイルを公開するようなものでもないと思いますので。


コメントを残す

メールアドレスが公開されることはありません。

*

この記事のトラックバック用URL