- 締切済み
バッチ組むとき楽にパス切りたい
複雑な操作を(半)自動化したいので、コマンドプロンプトで色々試しながらバッチを組んでいます。 バッチ組んでるといろいろ外部コマンドをネットから拾ってきたりして、ファイルが増えて、見づらくなるので、フォルダ掘って見やすく整理すると今度はパスが通ってないとか言われて、面倒です。 フォルダ構成も最初から完璧に定まるわけもなく、一通り片がつくまでフォルダ名も場所も変わり、パスも状況に応じてその都度切り直さないとならないので、その操作が面倒です。 今はとりあえず関係しそうなフォルダ群のうちの最上位のフォルダからtreeコマンドで一覧を出してパスを通したいフォルダ名をひとつひとつpathコマンドの引数へコピペしてますが正直やってられません。 しかもバッチがバグってるとプロンプトごと固まったりして落とさざるを得なくなるので、当然、環境変数も全部クリアされるので、毎回似たような操作をしてる気がします。 正直うんざりです。 どうしたらもっと楽にできますか。 楽したいから道具を使ってるのです。 強力な回答をお待ちしています。 なお環境はWin7 64ビットです。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- kon77
- ベストアンサー率70% (83/117)
度々すみません、No.3です。 間違いを見付けたので、訂正させて下さい。 前回、以下のように書かせて頂きましたが、 ---------------------------------- echo "■ PATHコマンドに置換 ■" FStr "%TEMP%\exe_list_2.txt" /rei "^(.*)$" "set PATH=%%PATH%%$1" > "%TEMP%\PATHのセット.bat" ---------------------------------- 正しくは、以下の内容です。 「%%PATH%%」の後に「;」が抜けておりました。すみません。 ---------------------------------- echo "■ PATHコマンドに置換 ■" FStr "%TEMP%\exe_list_2.txt" /rei "^(.*)$" "set PATH=%%PATH%%;$1" > "%TEMP%\PATHのセット.bat" ---------------------------------- 重複行の削除の件ですが、こちらの環境では、AWKでもPerlでも正常な重複削除を確認していますが、恐らく、何か環境が違う為に動作しないのかも知れません。もし、私がお教えした、ファイル数を限定したPerlでのエラーなら、もっと他のファイルも必要なのかも知れません。 uniqやsortコマンドは、入手しやすさ、ファイルサイズの小ささ、インストールしやすさでは、とても優れていますが、原因は分かりませんが、ものすごく稀にエラーが出るので、今回はお勧めはしませんでした。 ですが、エラーが出るのは、わりと大きくて、複雑な内容のファイルを処理しようとした場合に多い気がしますので、今回の様な比較的単純な処理ではエラーが出る可能性が少なく、良いかも知れません。 パイプ処理を行いたい場合は、以下の様にすると良いかと思います。前回と同様、ソフトフォルダのパスだけ変更して実行してみて下さい。こちらで動作確認はしてありますが、環境が違うと思うので、動作しなかったらすみません。 ---------------------------------- @echo off set ソフトフォルダ=C:\ソフト cd /d "%ソフトフォルダ%" dir /s /b "*.exe" > "%TEMP%\exe_list_1.txt" FStr "%TEMP%\exe_list_1.txt" /rei "^(.*)\\[^\\]*$" "$1;\n" | uniq | FStr /rei "\n" "" | FStr /rei "^(.*)$" "set PATH=%%PATH%%;$1" > "%TEMP%\PATHのセット.bat" call "%TEMP%\PATHのセット.bat" cd /d "%~dp0" del /q "%TEMP%\PATHのセット.bat" del /q "%TEMP%\exe_list_1.txt" ----------------------------------
- kon77
- ベストアンサー率70% (83/117)
No.3です。 回答を書き込んだ後に気が付いたのですが、私が回答した内容は、既に質問者さんがNo.2さんに対する補足内でおっしゃっておられたのですね。重複してすみませんでした。 Perlのサイズの件ですが、もっとサイズの小さなプログラムが宜しければ、「AWK」を使うと良いかと思います。 ■ AWK(Gawk for Windows) http://gnuwin32.sourceforge.net/packages/gawk.htm 「重複行の削除」の部分を以下の線内の内容に差し替えます。 ------------------------------ echo "■ 重複行の削除 ■" awk "!a[$0]++" "%TEMP%\exe_list_2.txt" > "%TEMP%\exe_list_1.txt" ------------------------------ 又、Perlも、今回のコマンドを実行するだけなら、実行ファイル「perl.exe」本体と、同じフォルダにあるdllだけで動作すると思うので、それだけどこかにコピーしておいて、インストールしたPerlはアンインストールすれば、合計で3MB程度で済むと思います。 私は、スクリプトやプログラムの知識が全くないのでこういう方法になりますが、もっとスキルのある方なら、Windows標準の機能だけで実現出切るのかも知れません。分かりませんが。 又、私はまだ全然AWKのスキルが無いので出来ませんが、「FStr」でやっている事も、本当はAWKだけで出来ると思います。 「FStr」は個人の方が作られた、恐らく世間的にマイナーなコマンドですが、ダブルクォーテーションと改行を簡単に扱えるので使っている次第です。
補足
重複行削除ですが動かなかったので ntuxtl016.lzh 内の uniq.exe を用いて uniq "%TEMP%\exe_list_2.txt" > "%TEMP%\exe_list_1.txt" としました。 これで一応動きましたが、パイプの左右で同時には使えないですね。 ファイルが利用中と言われます。 一時テキストファイル名を毎回ランダムにするようにすればいけるかも。 引き続きやってみます。
- kon77
- ベストアンサー率70% (83/117)
パスを通しやすくする工夫をいくつか挙げたいと思います。 ■ 方法1 - 環境変数編集ソフトを使う GUIのソフトを使って環境変数を編集する方法です。 下記のソフトをダウンロードします。 【eve(Environment Variable Editor)】 http://www.vector.co.jp/soft/win95/util/se271898.html ソフトを起動します。 ↓ 「編集モード」タブをクリックします。 ↓ 「ユーザー(○○○)の環境変数」をクリックします。 ↓ 下の欄で「PATH」をダブルクリックします。 ↓ 「値:」の右の欄に、パスを通したい実行ファイルがあるフォルダのフルパスを書き込みます。複数ある場合は改行で区切ります。 ↓ 「適用」をクリックします。 ↓ 「保存して適用」をクリックします。 ↓ ソフトを閉じます。 これでパスが通ります。 この方法のメリットは、GUIで簡単に編集出来ることです。 デメリットは、いちいち手動で編集しなくてはならない事です。 ■ 方法2 - 指定フォルダ下の、実行ファイルがあるフォルダを、自動でPATHにセットする あらかじめソフトを入れるフォルダを決めておき、バッチファイルの最初に、そのソフトフォルダ内の実行ファイルがあるフォルダを、PATHにセットする方法です。 バッチファイルの最初に、以下の線内の内容を記述します。 「ソフトフォルダ」の設定だけ環境に合わせて書き換えて下さい。 相対パスでも、絶対パスでも、カレントディレクトリから通ればいいです。 動作には、「FStr」と「Perl」がインストールされ、パスが通っている必要があります。 【FStr】 http://www.vector.co.jp/soft/winnt/util/se497060.html 【Perl(Strawberry Perl)】 http://strawberryperl.com/ ----------------------- @echo off echo "■ 設定 ■" set ソフトフォルダ=C:\ソフト echo "■ 実行ファイル一覧を作成 ■" cd /d "%ソフトフォルダ%" dir /s /b "*.exe" > "%TEMP%\exe_list_1.txt" echo "■ フォルダのパスを抽出 ■" FStr "%TEMP%\exe_list_1.txt" /rei "^(.*)\\[^\\]*$" "$1;\n" > "%TEMP%\exe_list_2.txt" echo "■ 重複行の削除 ■" perl -ne "print if!$line{$_}++" "%TEMP%\exe_list_2.txt" > "%TEMP%\exe_list_1.txt" echo "■ 改行を無くす ■" FStr "%TEMP%\exe_list_1.txt" /rei "\n" "" > "%TEMP%\exe_list_2.txt" echo "■ PATHコマンドに置換 ■" FStr "%TEMP%\exe_list_2.txt" /rei "^(.*)$" "set PATH=%%PATH%%$1" > "%TEMP%\PATHのセット.bat" echo "■ 出来たバッチを実行してPATHをセット ■" call "%TEMP%\PATHのセット.bat" echo "■ バッチファイルのあるフォルダに移動 ■" cd /d "%~dp0" echo "■ 掃除 ■" del /q "%TEMP%\PATHのセット.bat" del /q "%TEMP%\exe_list_1.txt" del /q "%TEMP%\exe_list_2.txt" ----------------------- この例では、「FStr」と「Perl」を使いましたが、同様のことが出来るなら他のコマンドでも構いません。 この方法のメリットは、指定したフォルダ下であれば、ファイルやフォルダを移動したりリネームしても、その都度再設定しなくてもいい点です。 デメリットは、あまりにもフォルダの数が多過ぎると「PATH」にセット出来ない点です。「Program Files」等は実行ファイルが多すぎて無理です。 ■ 方法3 - 自動で実行ファイルを個別にセットする 指定したフォルダ下の実行ファイルを個別にセットする方法です。 バッチファイルの最初に、以下の線内の内容を記述します。 「ソフトフォルダ」の設定だけ環境に合わせて変更して下さい。 動作には、「FStr」がインストールされ、パスが通っている必要があります。 ----------------------- @echo off echo "■ 設定 ■" set ソフトフォルダ=C:\ソフト echo "■ 実行ファイル一覧を作成 ■" cd /d "%ソフトフォルダ%" dir /s /b "*.exe" > "%TEMP%\exe_list_1.txt" echo "■ バッチファイルに置換 ■" FStr "%TEMP%\exe_list_1.txt" /rei "^(.*\\)([^\\]*)(.exe)$" "set $2=""$1$2$3""\n" > "%TEMP%\実行ファイルのセット.bat" echo "■ 出来たバッチを実行してPATHをセット ■" call "%TEMP%\実行ファイルのセット.bat" echo "■ バッチファイルのあるフォルダに移動 ■" cd /d "%~dp0" echo "■ 掃除 ■" del /q "%TEMP%\実行ファイルのセット.bat" del /q "%TEMP%\exe_list_1.txt" ----------------------- 実行する時は「%拡張子を除いた実行ファイル名%」の形式で実行します。 「aaa.exe」なら「%aaa%」です。 この方法のメリットは、沢山の実行ファイルがセットでき、指定したフォルダ下であれば、ファイルやフォルダを移動したりリネームしても、その都度再設定しなくてもいい点です。 デメリットは、コマンド実行の際、いちいち「%」で囲まなくてはならない点です。 ■ 方法4 - コマンドフォルダとソフトフォルダを決めてセットして使う フォルダ名は好きな名前でいいですが、 例えば、「ファイルリネーム」を目的としたバッチを作ろうとした場合、 以下のようなフォルダを作成します。 ファイルリネーム ┗SYSTEM ┣BIN ┗SOFT 実行するバッチファイルは「ファイルリネーム」フォルダ直下に置きます。 仮に「ファイルリネーム.bat」というバッチファイルを作成したとします。 そのバッチファイルの始めに、以下の線内の内容に記述します。 ----------------------- @echo off set SOFT=%~dp0\SYSTEM\SOFT set BIN=%~dp0\SYSTEM\BIN cd /d "%BIN%" ----------------------- 上記の例で言うと、 コマンドを追加したい場合は「BIN」フォルダに格納します。 実行したい場合は、環境変数等は使わずそのまま実行するか、 「"%BIN%\(コマンドファイル名)"」で実行します。 例えば「"%BIN%\aaa.exe"」等です。 何かソフトを使う場合は「SOFT」フォルダに格納し、 「"%SOFT%\(ソフトフォルダ名)\(ソフトファイル名)"」で実行します。 例えば「"%SOFT%\aaa\aaa.exe"」等です。 USBメモリ等で、他のPCに移して使う場合も想定しているのでこのようにしましたが、他のPCで使う予定が無いなら「C:\BIN」フォルダを作成して、そこにコマンドを入れてセットしてもいいです。他のバッチファイルとコマンドを共有出来ます。 又は、コマンドはWINDOWSフォルダに放り込んでもいいですが、OSリカバリーの時にバックアップが大変かも知れません。 ソフトフォルダも、Program Filesフォルダを使用するのであれば、「%ProgramFiles%\(ソフトフォルダ名)\(ソフトファイル名)"」で記述すれば良いかと思います。 この方法のデメリットは、ファイルやフォルダを移動したりリネームすると、パスが通らなくなる事と、記述が長くなることです。
お礼
回答ありがとうございました
補足
方法3は全バッチでコマンドは%で囲って書かないといけないんですね。それはちょっとバッチの行数も文字数も最低にしたいので避けたいです。 方法4は移動やリネームに対応しないということでこれも避けたいです。 方法1はGUIなので自動化できないですね。 ということで方法2を試したいと思います。 ってPerlってmsiだけで73.9MB?でかいですね…… まぁUnxUtilsも使ってるんだし今更仕方ないですね
- vaidurya
- ベストアンサー率45% (2714/5983)
WindowsはMS-DOSの時代から、HDDの管理について ユーザーの裁量に委ねるところが大きく、逆に不便な面もあります。 MS-DOSの時代から、一部の人は Microsoft社やApple社が無い時代からある UNIXでのディレクトリー構成を参考にした管理を行なって来ました。 UNIXの資産や文化は、コンピューターが大企業や研究機関などにだけあり 大勢で共用するものだった時代に始まり… 現在のMacOSXやFreeBSD,Linux系OSなどまで使い続けられています。 たとえばLinux系OSのUbuntuでは、一般的にこういったディレクトリー構成になっています。 /home /bin /sbin /usr/bin /usr/sbin /usr/local/bin 基本的にはbinディレクトリーは一般ユーザーが使うコマンドで sbinディレクトリーは管理者が使う、管理者権限が必要なコマンドです。 LibreOfficeやFirefoxやAudacityなども、専用のディレクトリーではなく /usr/binに実行ファイルが集約され、ライブラリー/usr/libに 全体の設定ファイルは/etcなど、個人設定は~/下に分離管理されています。 (~/はたとえばユーザーvaiduryaにとっての/home/vaiduryaを意味する特殊な記述です) MS-DOS系と比べてわかりにくい面もありますが 設定ファイルのバックアップを取る場合には便利な仕組みですし HDD容量の異常消費も、原因が起きやすい場所が特定しやすく対処しやすくなっています。 統合的なパッケージ管理があることによって、構成のわかりにくさも緩和されます。 たとえばあるソフトを削除しようというときに、探しまわる必要は無いし バージョンの確認もdpkg -i ソフト名で済みます。 whichコマンドによって、実際に実行されるコマンドが どこに置かれている実行ファイルであるかを確認することもできますから 探すことも、そうむずかしいことではありません。 http://www.atmarkit.co.jp/fwin2k/win2ktips/319which/which.html バッチファイルに相当するシェルスクリプトは、専用のディレクトリーを決めても構いませんが 通常は/usr/local/binに置くようになっています。 これはUbuntuとして管理するパッケージ以外の 管理者が追加した、一般ユーザー向け実行ファイルの置き場所です。 独自の管理者用シェルスクリプトなどは/usr/local/sbinに置きます。 自分で決めた場合は、自分で実行pathを再設定する必要が生じます。 Windowsではpath設定は話題になりにくいようですが 管理ルールを決めて、path設定を済ませてしまえば あとは、それほど面倒くさいことはなくなると思います。 こういった管理概念を、MS-DOS系の環境にそのままには使えませんが 現在のWindowsでは、シンボリックリンクなどがありますから 組み合わせて管理することもできるはずです。 あと、Windowsのコマンドプロンプトと呼ばれるCUIシェル(CMD.EXE)は MS-DOS互換をひきずった、機能的に進化の袋小路にはまったソフトのようです。 (本来のコマンドプロンプトとは"C:\Documents and Settings\vaidurya>"を指します) CMD.EXEの拡張を諦めたMicrosoft自身が、WSHを配布していましたが 一般大衆には知られず、むしろウィルス作成者に活用されたりもして… 現在では、再々構築されたWindows PowerShellが配布されています。 http://ja.wikipedia.org/wiki/Windows_PowerShell 用途によっては、PowerShellを使うほうが効率的になるはずですし UNIX系OSでのスキームを模倣する場面では 普通に、Linux系OSやFreeBSDを用いるほうが効率的かもしれません。 これは仮想マシンなどによって、使いやすくなったと言えます。 私自身は、単純なシーケンシャル処理のシェルスクリプトは書いても 複雑なシェルスクリプトは、ネットから入手したものや、そのアレンジしか使いません。 自分がバグを作ることが、自動化における最大の不安ですから(笑)
補足
確かにネットで拾えるさまざまな有用なソフトは私も散々お世話になっていて、その背景がUnix文化から来ていることも知っていますのでその背景も(フォルダ構成とか)知っておくに越したことはないとは思います。 WSHとかPowershellとかはちょっと見ただけでめまいがしましたのでなるたけ近づきたくありません、今でも一部利用はしていますが深入りはごめんこうむります。 回答の趣旨としてはフォルダ構成はUnixを参考に自分で最初に決めとくということでしょうがそれでは全然追いつかないので質問しました。 例えばバッチ書いていてもコマンドが長いと見づらくて厭になるので、echoひとつとってもeというバッチをかぶせてバッチファイル内文字数を最小化したいくらいです。 3行以上書きたくないとか思っています。 当然大量の小バッチが出来るのでその整理をいかに行うかです。 バッチが実際に実行するコマンドは各ソフト名のフォルダというか、Zipを解凍したフォルダにそのまま置いておきたいです。 質問してからまた自分で考えてみたのですが関係するフォルダ群の最上位フォルダはほぼ定まっているので、その配下の全フォルダを再帰的に探索してリストアップしてpathコマンドの引数に渡して実行みたいなバッチというか処理を考えて、全バッチの先頭で実行するような仕組みを入れられないかなと思いました。 実行したバッチを基点に上位下位何階層まで容赦なくパス通すみたいなのもいいかもしれませんね。 というような支援ソフトや支援バッチや、要するにやりやすい環境が整っていないと、勢い込んで作り始めても途中で訳わかんなくなって投げ出すというか今までずっとそうなってる気がします。 要するに何から何まで全然足りず全く追いつかず離される一方です。 Unixの話とかネットで同じ話を散々見てる気がしますが全然身についてないというかやりたいことには全然追いつかないですね しかも情報セキュリティがどうとか言い出されたらもう発狂です
- over_the_galaxy
- ベストアンサー率25% (104/408)
エクセルVBAを使ってます。ワークシートに望みのコマンドを書き、VBAで(1)バッチファイルに書き出し、(2)フォルダにコピー(3)実行させます。 参照機能wl使えばパスの編集も楽です。VBAはネットで拾いました。
補足
オフィス持ってませんつかうきもないです
補足
AWKで重複行削除の箇所でエラー出ているなと思って直そうとしたのですが分からなかったのでuniqにしました。 後でよく見たらcmd/v下で実行していました。 普通の環境ではAWKでもPerlでも問題なく動きました。 uniqが稀にとはいえエラーが出るとは知りませんでした。 そういう話を知るとなるべく避けたほうがいいかなと思います。 ただFStrはcmd/v下(setlocal enabledelayedexpansion と endlocal で挟んだあいだ)での動作はどうなのか気になります。 いずれにしても調べながらやっていきたいと思います。 パイプ対応ですがパイプの両端ともバッチの場合で、それぞれの中身の先頭に今回回答頂いた内容を付加した場合、やはり プロセスはファイルにアクセスできません。別のプロセスが使用中です。 と言われてエラーになるので、 exe_list_1.txt と PATHのセット.bat をそれぞれ exe_list_1_%~z0.txt と PATHのセット_%~z0.bat としたら動きました。 とりあえずこれで行こうかと思います。(あと、別バッチにしてcallで呼ぶようにするのだけやってみます) もっといい方法があったら教えてください。