◎正当な理由による書き込みの削除について: 生島英之 とみられる方へ:【.cmd】 バッチファイルスクリプト %12 【.bat】©2ch.net ->画像>4枚
動画、画像抽出 ||
この掲示板へ
類似スレ
掲示板一覧 人気スレ 動画人気順
このスレへの固定リンク: http://5chb.net/r/tech/1489207631/ ヒント: 5chスレのurlに http ://xxxx.5chb .net/xxxx のようにb を入れるだけでここでスレ保存、閲覧できます。
達人の方々!お教えください set文による文字列の置き換えで =を置き換えたいのですが どのように記述すればよいのでしょうか?
>>5 setの文字列置換では無理
=の個数が決まっているのならforでderims==
不特定なら一文字ずつ=かどうかを判定し=なら置換したい文字列を付け足し
テストしてないから不備があるかもだけど以下みたいな感じで出来ると思う
:ReplaceEqual
if "%~1"=="" (echo ERROR&exit /b)
set "str=%~1"
set output=
:CheckEqual
if not defined str exit /b
pause
if "%str:~0,1%"=="=" (
set "output=%output%置換後文字列"
set "str=%str:~1%"
goto :CheckEqual
)
set "output=%output%%str:~0,1%"
set "str=%str:~1%"
goto :CheckEqual
済まん pause テストするつもりで入れてたのを消すの忘れてた まあそのままテストしてみて
:ReplaceEqual set "str=%~1" set output= :CheckEqual if "%str:~0,1%"=="=" ( set "output=%output%置換後文字列" set "str=%str:~1%" ) else ( set "output=%output%%str:~0,1%" set "str=%str:~1%" ) if defined str goto :CheckEqual exit /b
>>6-8 ありがとうございます
色々試して見ます
>>8 と同じだけど、もう少し使いやすいI/Fにしたもの
@echo off
rem 文字列中には、",%(1つのみ) を入れないこと
set "var==abc=def=!#$&'()=^~|-+*;:{}<>,./?\_%%"
call :replace var "=" "="
echo "%var%"
rem savety stopper
goto :eof
:replace
setlocal
set i=0
set s=
:replace_loop
call set "c=%%%1:~%i%,1%%"
if not defined c (endlocal&set "%1=%s%"&goto :eof)
if "%c%" equ "%~2" (set "s=%s%%~3") else (set "s=%s%%c%")
set /a i+=1
goto :replace_loop
cmderいいな この手のツールで表示が崩れたりせずまともに動くやつ見るの初めてだ
for /r %%i in (*.jpg) のようなコマンドで取得した絶対パスをカレントフォルダとの相対パスに変換するにはどうするのが一番ですか? 現在はsetコマンドの置換機能でカレントフォルダの部分のパスを消しているんですがパスに変な文字列が入っていると誤作動を起こしそうで少し不安です。 もっとスマートなやり方はありますか?
>>14 実際の有効なパスが対象なんだから
問題となるのは上に出てきたequalを含んだフォルダがある場合だけだろう
setlocal
echo %cd%>tmpfile
for %%i in (tmpfile) do set /a size=%%~zi-2
del tmpfile
if %size% neq 3 set /a size+=1
for /r %%i in (*.txt) do (
set "p=%%~i"
call set "p=%%p:~%size%%%"
call echo ".\%%p%%"
)
endlocal
肝心なのは、文字列操作、表示まで扱う場合は 文字列を必ず""で括るようにすること & % ^ 等を含んでると括ってないとおかしくなる
>>17 ファイルサイズじゃ根本的にダメだったね
(それにecho %cd%も""で括ってなきゃいけなかったし)
call :length "%cd%" n
for /r %%i in (*.txt) do (
set "p=%%~i"
call set "p=%%p:~%n%%%"
call echo ".\%%p%%"
)
goto :eof
:length
setlocal
set s=%1
set n=0
:length_1
call set "c=%%s:~%n%,1%%"
if defined c set /a n+=1&goto :length_1
if %n% neq 5 set /a n+=1
endlocal&set /a %2=%n%-2
goto :eof
訂正 call :length cd n for /r %%i in (*.txt) do ( set "p=%%~i" call set "p=%%p:~%n%%%" call echo "%%p%%" ) goto :eof :length setlocal set n=0 :length_1 call set "c=%%%1:~%n%,1%%" if defined c set /a n+=1&goto :length_1 if %n% neq 3 set /a n+=1 endlocal&set /a %2=%n% goto :eof
>>15 ありがとうございます
文字列を置換することばかり考えていたのでカレントフォルダ分の文字数を削るという発想に行き着きませんでした
これで何とかなりそうな気がします
どなたかお詳しい方、ご教示ください windows7を起動後、自動で特定のアカウントパスワード入力後にログインし、 ログイン後、デスクトップの特定座標を自動でクリックするという操作を行わせたいです このような処理はbatファイルで可能でしょうか? win7初期状態にインストールされているものであれば他のものを使用してもよいのですが。 キーワードだけでも結構ですので、お助けいただければ幸いです
ログインとはWindows7の登録ユーザーってことか? それともWebブラウザを起動してどっかのサイトにログインするってことか? あと何故マウスクリックなのか? デスクトップに表示してるアイコンなら別に直接起動できるだろうに
だいぶ使い道ないけど、DIRって複数フォルダの内容を1回で表示できるんだね。 DIR C:\tmp C:\tmp2
for文が同一フォルダに自分で出力したファイルを 一つだけ拾っちゃうんだけど、何か対策はありませんか? for %%I in (*.jpg) do copy %%I %%~dpI_%%~nxI って感じに処理すると 1.jpg 2.jpg → _1.jpg _2.jpg __1.jpg となっちゃう…
for /f "delims=" %%a in ('dir /a-d /b *.jpg') do
バッチファイルで echo %* とすると引数がすべて表示されるけど %0=自分自身だけ無いのはなんで? *で0だけハブられるなんて可哀想……
少し考えれば分かりそうなものだが %cmdcmdline%
バッチ書くのにオススメのエディタあったら教えて 最近目がめっきり弱くなって来たので色分け表示とかの視認性上がるものや 便利そうな機能があるものを知りたい 頻繁に使うわけじゃないからこそ探すの面倒で先人の知識をお借りしたい
>>33 VisualBatは?
文字に色もつくしいろいろ設定できるよ
batをexe形式にすることもできる
マジレスすると目が悪いならでかいモニタ買ってフォントサイズでかくするのが一番良い PowerShell、Ruby, PythonとかならVSCodeでブレークポイント張ったり変数のインスペクトしたりできるけど その手の支援機能が全く期待できないBatじゃどれ使っても同じだろう 手に馴染んだエディタ使えばいいしないならフリーのどれか一つ覚えればいい キーワードの色分け程度なら大抵用意されてるし VisualBatはちょくちょく見かけるけどそれ専用の環境を覚えるくらなら普通のエディタ使ったほうがいい気がする 個人的にはBatから別の言語のコード書いて呼び出す事が多いし 自作マクロになるけど ↓みたいなコードを一つのファイルに書いて##!!に挟まれたカーソル位置のコードを切り出して実行する機能が 言語の学習やちょっとしたテストに便利で気に入っているのでエディタマクロ覚えて作ってみるのお勧め ##!! echo test echo hello ##!! for test for %i in (a,b,c) do echo %i ##!! calc test set a=1 set /a a+=2 echo %a%
>>33 黒背景に白地の文字が視認性あがるよ
フォントはゴシックで文字サイズも大きくする
俺の使ってるのは一般的にはオススメではないのでどうかと思うが
(New)QXエディタ(一応シェアウェアだが未登録でも機能制限も期間制限も無い)
>>39 確かに、目のいい人にとってはそうかもしれないけどね
コマンドプロンプト画面がエディタ画面だと思ってもらえれば想像できるよね
目のいい人がコメントしたって意味ないだろ 老眼やかすみ目で文字が読みにくくなったらわかるよ 特に、カンマとピリオドの区別が付かないとストレス溜まるぜ
>>33 サクラエディタ入れて
IPAゴシックフォントにする
そういえば昔のホスト端末とかって黒背景に緑字が多かったよね? あれってなんでだろ?
>>45 グリーンディスプレイがあったからじゃね?
緑やオレンジの蛍光体の方がTVの白蛍光体より刺激が少ないから採用されていたらしい
>>40 適当な画像エディタのスポイトで抽出してみればわかるけど
コマンドプロンプトは黒と白じゃなくて黒とグレー
理由は目への配慮
DQも同じ
皆様たくさんのレスありがとうございます VisualBat試してみました デバッガとしては便利そうですがTab文字打てないのでエディタとしてはまだちょっと使えなさそうです for や if の()で自動インデントとかしてくれるようになると便利かも 今後の更新に期待します 他、挙げて頂いたアドバイスも順次時間が取れ次第試して行きたいと思っております 次はサクラエディタを試用する予定。他候補にMery、QX コマンドプロンプトは color 07 不透明度80 で使っております かすみ目、乱視、老眼、ド近眼、何れも酷いです 他に思い付いたアドバイス等ございましたらよろしくお願いします
>>43 フォントはVLゴシックのほうがいいと思う
>>50 あのフォントゼロに斜線が入ってるから使ってる
ms製wgetなんてあったんだな
何故か異様に遅いが
bitsadmin /Transfer htmlget
c:\logo.png
フォントはMyricaがClearTypeと相性がいい
VLゴシックは行間空き過ぎ
同じ行数が表示出来るようフォントサイズで調整した場合
VLゴシックのフォントサイズ10に対しIPAゴシック12、MSゴシック13
やたらと空行入れたがる脳みそスカスカの空行厨が好みそうなフォント
自分にはIPAゴシックよりVLが良い点が見当たらないので
>>50 さん、どの辺が良いのか具体的に教えていただけると助かります
>>54 これは知らんかった
バッチファイルで夜間にダウンロードとかに便利だな
>>54 動かなかったんで/helpしてみたら、WindowsXPのbitsadminには/Transfarが無かった(version 1.0 [ 5.1.2600.0 ])
調べてみたら、
Windows XP Service Pack 2 サポート ツール
https://www.microsoft.com/ja-jp/download/details.aspx?id=18546 をインストールすればいいことが判った
version 2.0 [ 6.6.2600.2180 ]
Myrica良いね |が破線なのと\→\バックスラッシュに違和感あるけど慣れればこっちの方が見分け楽そう
set test=%1 for /f "delims=" %%f in (%test%) do ( E:\test\test.bat %%f ) 上記のfor処理にテキストのファイルパスを一つずつ読み込ませて専用batで処理した後に 全部終わったらシャットダウン処理をしたいのですが ループ処理に割り込ませる方法って何かありますか?
質問の意味が不明瞭 全部終わった後でいいならforの後にshutdown書けばいいんでないの? for中に割り込ませたいのは何故?
set test=%1 for /f "delims=" %%f in (%test%) do ( E:\test\test.bat %%f ) shutdown /S /T 30 単純にこれでうまくいかなかったので割り込ませる必要があるのかと思い質問しましたが やっぱりそんなわけないですよね・・・ 単純なミスをしてる可能性が高そうなのでもう一回見直してみます
callしてないからtest.batから帰ってこないだけでは
あちゃーほんとだ 普通に動いてたから気づかなかった・・・ アホですね ちょっと修正してテストしてみます 指摘ありがとう
ソフトを起動した際に出るライセンスキーを入力する画面に値を自動でいれたいです。 batで可能でしょうか?
batでgrep検索をしようと思ってるんだけど、 検索結果にファイルのフルパスを出力する方法を教えてください>< 現状だとファイル名+行の内容しか出ない・・・
複数のファイルがあり、ぞれぞれ中身が fileID: aaaa within( ); や fileID: akf within( ); などfileID: ~ within();は固定です。 各ファイルのaaaaやakfを読み込みの際に変数に取り込みたいのですがどのように書けばいいでしょうか? fileID: aaaa within(はファイルの一行目なので set /p fl=< %inputFile% でとれました。
テストしてないけどこんな感じ。必要ならusebackqとかも。aaaaに&とか入るならsetでクオートする必要がある for /f "tokens=2* delims= " %%a in (%inputFile%) do ( set ID=%%b goto :NEXT ) :NEXT または set /p fl=< %inputFile% for /f "tokens=2* delims= " %%a in (%fl%) do set ID=%%b または for /f "tokens=2* delims= " %%a in ('findstr /b /c:"fileID" "%inputFile%"') do set ID=%%b
>>69 "within("しか取れませんでした。
書いたコマンドとテストした対象ファイルの1行目をコピペで貼ってみ
助けて下さい! 毎月第二木曜日の16:00になったら Aフォルダに入っているgファイルにBフォルダに入っているgファイルを上書きする batファイルを作って下さい よろしくお願いします
>>72 ファイル上書きのBAT(c:\xxx.bat)を作成してタスク登録する
schtasks /create /sc monthly /mo second /d thu /st 16:00:00 /tn title /tr "c:\xxx/bat" /ru username /rp userpassword
set txt="C:\scr\a.txt" for /f "delims=, usebackq tokens=1,2,3,4,5,6,7,8" %%i in (%txt%) do ( set /a X="(%%j-%%i)+(%%l-%%k)+(%%n-%%m)+(%%p-%%o)" ) echo %X% forを使った計算について質問ですがa.txtから数値を抜き出し計算したいのですが最後の二つが空の場合があり この場合は%%pと%%oですがその場合はエラーになって強制終了してしまいます gotoを使う方法は思いついたのですが他に空だった場合にゼロを代入するなどは可能でしょうか?
set txt="C:\scr\a.txt" for /f "usebackq tokens=1,2,3,4,5,6,7,8 delims=, " %%i in (%txt%) do ( set /a X=%%j-%%i+%%l-%%k+%%n-%%m, po=%%p-%%o ) set /a XX=X+po echo %XX%
>>76 空の場合に1が代入されてエラーを回避できました
サンクス
特定のフォルダ内のテキストファイルを処理するバッチを作りましたが @echo off for /f "usebackq delims=" %%i in (`dir /B /S "E:\text_sc\*.txt"`) do ( echo %%i call E:\work\syori.bat "%%i" ) syori.batで処理したテキストを忘れないようにリスト化(syorizumi_list.txt) aaa bbb ccc のように処理したテキストの名前だけ縦に追記 次回から新しいテキストファイルが同じフォルダに出来た場合にsyorizumi_list.txtの 処理済みのテキストを除外して処理したいのですが コマンドのアドバイスを頂けないでしょうか
>>79 もし、その入力ファイルをその後弄らないのならファイル属性を弄るのがいい
例えば、アーカイブ属性を削るとか読み取り専用属性にするとか
そうすれば、forの中のdirに/aで分別できる
それが無理な場合は、こんなかんじでファイルに登録されているかどうかチェックするとかかな
findstr /x "%%~ni" syorizumi_list.txt >nul
if errorlenel 1 (
echo %%i
call E:\work\syori.bat "%%i"
)
)
>>80 レスありがとうございます
読み取り属性の方は最終手段としてとりあえず書かれたコマンドを追記してテストしていますが
エラーで強制終了してしまいます・・・
ヒントは頂けたのでちょっと考えてみます
処理済みファイルを下位ファルダに移動させるとかじゃダメなの? それが1番楽だと思うけど
ダメではないですし意地になってるだけです・・・ すいません どうしようもなければそうしおうと思います
>>81 ただのtypoだから(errorlevel)
あと処理済ファイルの指定はフルパスにしないとダメかも
あと、移動させるなら下位フォルダはダメだよ dir /sではそれも対象だから
>>84 修正したら動きました!
ありがとうございます
ただsyorizumi_list.txtに
aaa
bbb
ccc
とあったらaaaしか除外してくれませんね・・・
もう少し調べてみます
>>86 まあこっちが悪いっちゃ悪いんだけど、これくらい修正して使って欲しかった
/c:"%%~ni"
>>87 眠すぎたのと集中力が散漫で気づいてないだけでした・・・
すいません
それと指摘の通り/c:に変えたら期待通りの動作になりました
サンクス!
>>88 その言い方に嫌な感じがするんだがちゃんと引数の意味を調べて使ってるよね
/x /c:"%%~ni"としてるんなら、変な勘ぐりスマン
>>89 /x /c:"%%~ni"で問題なく動作しています
細かいところまでありがとう
こんなろくに理解せずそのまんまコピペして使ってるとトラップに引っかかるぞ
下位フォルダに移動することも検討してるなんてレスから /sが必要だとも思えんよね
もし/sが意図通りだったら aaa.txt aaa\aaa.txt なんて状況どうするんだって話だし
>>89 > その言い方に嫌な感じがするんだがちゃんと引数の意味を調べて使ってるよね
同意
88の1行目で奴の人物像がすべて分かる
引数 %1 %2 ,, は%9 までだが shiftで取り出せば%10以上でも取り出せた
Cドラのdown配下のmp4とaviを DドラTozakaruzoSaikonkaraに集約してコピーしたいときはどうするの? XCOPY "C:\down\*.mp4” "D:\TozakaruzoSaikonkara\" /d /e /h /r /y XCOPY "C:\down\*.avi" "D:TozakaruzoSaikonkara\" /d /e /h /r /y ワイルドカード使いたいけど、eroやmoroのところが難しい for文の記述の方がいいなど、よろしくお願いします。 C:/ ├down/ │ └ ero/ │ └ 111.mp4 │ └ moro/ │ └ xx2.avi │ └ zzz.mp4 │ └xxx.avi D:/ ├TozakaruzoSaikonkara/ │ └ 111.mp4 │ └ xx2.avi │ └ zzz.mp4 │ └ xxx.avi
>>96 cd /d c:\down
cd d:TozakaruzoSaikonkara
for /r %%i in (*.avi *mp4) do copy /y "%%~fi" d:
cd d:\TozakaruzoSaikonkara の方がいいか
もしフォルダが無いなら md d:\TozakaruzoSaikonkara 追加してくれ
*.mp4 だった 穴だらけだな 俺もボケてきたか
>>98 おー、inの句に並列できるんですね
%%~fiのfはfileの意味でしょうか
いずれにしても無事コピーされました
応用も効きそうなので調べて利用させていただきます!
ありがとう
いや、フルパスかな 初めてだったので、楽しみます ありがとう
>>103 俺がもっといいやり方がないか調査するからとりあえずmoroフォルダをうp!
>>98 ドライブとディレクトリの違いであるのか、コピーと移動の違いであるのか、 教えていただけたらうれしいです。 >>96 で、同じドライブの別フォルダに移動したいとき、下記教えていただいたコマンドを変えて実行すると、 別ドライブのときのようにコピーがされない状況です。 cd /d c:\down cd c:\TozakaruzoSaikonkara for /r %%i in (*.avi *mp4) do move /y "%%~fi" c: --------- 下記の用に移動したい C:/ ├down/ │ └ ero/ │ └ 111.mp4 │ └ moro/ │ └ xx2.avi │ └ zzz.mp4 │ └xxx.avi C:/ ├TozakaruzoSaikonkara/ │ └ 111.mp4 │ └ xx2.avi │ └ zzz.mp4 │ └ xxx.avi for /r c:\down %%i in (*.avi *.mp4) do move /y "%%~i" c:\TozakaruzoSaikonkara
>>106 ありがとうございます!
比較して、代入の引数iに違いがあるし、もう少し勉強します。
また、わからないことなど出てくるかもしれませんが、その時はよろしくお願いいたします。
参考に言っておくが () の中の引数なんだが、ワイルドカード以外は要注意だ 例えば (*.avi *.mp4 sukebe.jpg) とかにすると 各ディレクトリに sukebe.jpg が無くても強引にコマンド実行してエラーになったりする
moroとかsukebeとか名付けがオッサン臭いんだがw
DIRコマンドでは*を使って検索みたいなことが出来ますね。 【コマンド】 C:\>dir /s /b C:\Windows\System32\host* 【実行結果】 C:\Windows\System32\hostname.exe C:\Windows\System32\dllcache\hostname.exe C:\Windows\System32\drivers\etc\hosts 他にもっと複雑な検索も出来るのでしょうか?
あと「DIR /?」で出てくるヘルプにはこの機能について触れられていないのはなぜなのでしょう?こんなに便利なのに。
>>111 windowsXPで恐縮なんだが、Windowsヘルプ(ヘルプとサポートセンター)では、
Dirの項目の説明の中で、ワイルドカード関係のものとして以下のものが書いてあったよ
解説
・複数の filenames を使用する
複数の filenames を使用できます。スペース、カンマ、またはセミコロンでファイル名を区切ります。
FileName でワイルドカード文字 (? と *) を使うと、ファイルのグループを表示することができます。
・ワイルドカードを使用する
ワイルドカード (? と *) を使うと、ファイルとサブディレクトリのサブセットの一覧を表示できます。
例
ドライブ C のすべてのディレクトリで、拡張子が .txt のすべてのファイルの一覧を表示するには、次のように入力します。
dir c:\*.txt /w/o/s/p
各ディレクトリにある拡張子が .txt のファイル名が、アルファベット順にソートされた一覧がワイド形式で表示されます。
画面単位で一時停止し、キーが押されると次の画面が表示されます。
>>111 つまりコマンドの内蔵ヘルプは簡略版ってことなんだ
それと、なんかちょっと検索してみたら
Windows10には「ヘルプとサポート」がないらしい
なのでオンラインでのコマンドラインリファレンス
https://technet.microsoft.com/ja-jp/library/cc755121%28v=ws.10%29.aspx XPの「ヘルプとサポート」には
「コマンドラインリファレンス」の他にも、
「新しいコマンドラインツール」
「コマンドシェルの概要」(ここにパイプやリダイレクトの説明が載っている)
ってのがあったんだけどなあ
質問があります。 ちょっと事情があってすべての引数をダブルクオーテーションで囲って実行しなければならなくなりました。 例えばこんな感じで "C:\Software\ffmpeg\ffmpeg.exe" "-i" "%~1" "-vcodec" "utvideo" "-acodec" "pcm_s16le" "%~dpn1_test.avi" ffmpegでは正常に動くことを確認したのですが他の一般的なソフトウェアもこのような起動方法で動作すると考えてもいいのでしょうか?
とあるファイルの中身の文字列を置換したいのですが、何かいい方法はありますでしょうか? とあるファイルはtxtファイルではないですが、テキストエディタで開くと文字列が書いてあります。
全部テキストならともかくそれ以外のバイナリファイル内の置換はcmdじゃ無理だろ WSHとかPower Shellとかで探せ
テキストファイルだけど、拡張子がtxtではないファイルのことです
findstr である程度のことはできるけど、置換の条件とかが複雑になってくるとしんどい。 外部コマンドが使用可能なら、onigsedとか、SEDを使った方が多少は楽。
>>119 拡張子になんの意味があると思ってるの?
なんかそのレベルの知識だったら、メモ帳でも使った方がいいと思うよ。
>>119 ren Nullpo.unko Nullpo.txt
バッチファイルからシリアルポートを簡単に読み書き出来る手段って無いですかね? 古くはCOM?を使う方法が有名ですがBluetoothなどで作られた仮想シリアルポート?には使えないようです
>>123 232C→USB変換ケーブルみたいなのあったような
そもそもバッチファイルって何? CでもBasicでもなく、メモ帳の拡張子をbatに変えるだけで良くて、 コマンドブロンプトとかいう、MS-DOSと何が違うのかわからないような画面で動いて、 何なの?
CだってBASICだってメモ帳の拡張子を適当に変えれば行けますよ
>>126 >メモ帳の拡張子をbatに変える
notepad.exeの拡張子をbatに変えたら動かなくなりますよ
>>129 なんでメモ帳って書いてあるのにnotepad.exeをいじるわけ?
>>130 お前の言う「メモ帳」とはnotepad.exeでない何か他のものなのか?
>>126 についていうなら、その辺のいい加減さが理解を妨げてると言える
とにかく
>>126 は色々とおかしい
どこから突っ込めばいいのかわからんくらいにアチコチおかしい
PC初心者板ならともかく、なぜム板にこんな人が居るんだ?ってレベル
迷い込んできたのか?
説明はできないが揚げ足は取れる、ということですね。
コピー系コマンドのコピー速度って 遅 copy < xcopy < robocopy 早 で良いですよね? これはVista、7、10のどのOSでも同じでしょうか?
>>141 コマンド打ち込むにも時間がかかりますから一理ありますね。copyは引数指定も直感的だし…
って常にコマンド手打ちする訳でもないですし!w
プラスバッドって、何か格好いいな。 カンマバットはダセェけど。
では、 £.bat γ.bat ラプラスバットと、ガンマバットでは、どうだろう?
@.bat や =.bat ファイルを作ることはできるが、実行しようとしてもコマンドプロンプトに無視されて実行できなかった
@.bat はフルパスで C:\work\@bat ってするか、キャレットでエスケープして ^@.bat で実行できる =.bat はフルパスでもダメだけど、キャレットでエスケープすればいける
>>147 キャレットって何かわからなかったが、^をつけることなんですね
^@ や ^= でたしかに実行できました
すみません助けてください 遅延関数を宣言してるところから、下記の親ディレクトリの名前だけ引くサブルーチンに ファイルフルパス投げて、戻そうとしているのですが for文のところでDEST_DIRに値が入らなくて困っています windows7環境で遅延関数について調べているのですが なんで値が入らないのかわからず。 %%Pをechoすると中身が表示されるのですが それをSETするときに何をやっても入りません。。。助けてください :GET_PARENTDIR setlocal enabledelayedexpansion SET PathLF=%1 SET PathLF=%PathLF:~0,-1% SET PathLF=!PathLF:\=^ ! for /F %%P in ("!PathLF!") do SET DEST_DIR = %%P endlocal && set DEST_DIR = %DEST_DIR% echo %DEST_DIR% exit /b
>>151 これって例えばc:\aaa\bbb\ccc\test.txtってファイルを投げたら
最終的にtest.txって文字を得たいの?
cccを得たいの?
>>151 まずは
SET DEST_DIR = %%P
endlocal && set DEST_DIR = %DEST_DIR%
の空白がいけないのでは?
SET DEST_DIR=%%P
endlocal && set DEST_DIR=%DEST_DIR%
>>154 後輩にその空白を入れられたことがある
「可読性を良くしようと思って…」って言ってたな
普通の高級言語やってる奴は=の前後に空白入れただけで不具合起こるなんて考えもしないわな
コマンドプロンプトはホント昔の仕様を引きずり過ぎだわ
setlocal enabledelayedexpansion使うとファイル名に!が入ってるとめんどくさいから極力使わないようにしてるんだけど俺だけ?みんなはどうしてる?
>>155 C言語で言うマクロ置換みたいなもんだからしょうがない
もう新規の奴はPowerShellに移行するしかない
名前ソートで上に持ってきたいフォルダには名前の頭に!をつけてる
スペースが入ったファイル名からスペースを取り除くには一行では無理ですか?
こんな感じ? set "File=%~1" & ren "%File%" "remove=%File: =%"
間違えた set "File=%~1" & ren "%File%" "%File: =%"
バッチでよく使う pslist.exe はプロセス名が日本語だと間違える pslist v1.4 sysonternals
フォルダD:\XXXX直下の、 AAAA、BBBB、CCCCの3つの隠しファイル(拡張子なし)を、 定期的にE:\backupフォルダにバックアップするためのバッチファイルを作りたい フォルダXXXX以下には、YYYY、ZZZZというフォルダがあり、 この下にもAAAA、BBBB、CCCCと同名のファイルが存在するが、 それはバックアップしなくていい copyコマンドでは隠しファイルはコピーできない xcopyコマンドではサブディレクトリ以下の同名ファイルもコピーされてしまう バッチファイルで処理するためにはどうすればいいのでしょうか? できればアトリビュートはいじりたくないです よろしくお願いいたします
>>163 xcopyでAAAAなどのファイルを一つずつ指定してコピーするというのは?
>>165 実験してみたんですが、
xcopy D:\XXXX\AAAA E:\backup\
とすると、backupフォルダには、
AAAA
\YYYY\AAAA
\ZZZZ\AAAA
の3ファイルがコピーされちゃうんですよ
\YYYYと\ZZZZのはいらないのでどうしたもんかなと質問させていただきました
>>166 こちらの方でもテストしたけど1ファイルだけコピーになるんだけどな
なんでだろ
>>167 テストありがとうございます
あれ?
なんか余計なスイッチ入れるとかしちゃってたかな?
今出先なんで帰ったら再度実験してみます
>>161 cd /d "%~dp1" & set "File=%~nx1" & call ren "%%File%%" "%%File: =%%"
>>163 cd /d "D:\XXXX"
for %%i in (AAAA BBBB CCCC) do xcopy /h /y "%%~i" "E:\backup"
以前こちらで聞いて試行錯誤しているのですが、何分初心者で四苦八苦しております。 そこでご教授願いたいのですが、 @rem 引数有無と引数名チェック if "%USR_INPUT_STR1%"=="" goto ERROR echo;%USR_INPUT_STR1%|findstr /R /C:"^http" /C:"openrec" >NUL||(echo "%1" を処理できません) && goto ERROR @rem URLのアドレスとHTMLを環境変数へ設定 set ADDR=%USR_INPUT_STR1% for %%I in (%USR_INPUT_STR1%) do set HTML=%%~nxI @rem HTMLダウンロード curl -L --max-redirs 10 -R -O %ADDR% if not %ERRORLEVEL%==0 goto ERROR @rem HTMLから文字列抽出 for /F "tokens=2 delims=<>| " %%I in ('type %HTML%^|findstr /R /C:"<title>"') do set TITLE=%%~I for /F "tokens=3 delims=, " %%I in ('type %HTML%^|find /I "m3u8"') do set TARGET=%%~I ffmpeg -c copy "%TITLE%" -i "%TARGET%" pause exit :ERROR echo 引数が無効のため処理できませんでした pause exit このままだと、ファイル名がUTF-8で文字化けしてしまいます。 これを、面倒なのでファイル名で出力したいと思ったのですが、正規表現が弱く全く前に進みません。 丸投げで申し訳ございませんが、どうか手直ししていただけませんでしょうか。 よろしくお願い致します。
>>170 よく分からないけどbat自体をUTF-8で書いてchcp 65001というのは?
>>172 それも考えたのですが、不特定多数のPCで使う機会があるので手間が増えてしまうなと思い諦めました。
そこで、URLからIDとなる文字列を抽出してそれをファイル名に使おうと考えました。
参考URL:
https://www.openrec.tv/live/7cuVKOAY3lv この末尾の7cuVKOAY3lvの部分だけを、TITLEに代入したいと思ったのですが、思うようにいかなくて・・・。
結局、実行batのディレクトリ内にnkf32を導入し、 nkf -s --overwrite %HTML% と書き加えて対処致しました
フォルダの中に、あああ_1.flv あああ_2.flv … あああ_100.flvのようなファイルがあるときに、あああ_1.flvをあああ_001.flvのようにリネームしたりできないんでしょうか
お~瑠璃ね~むで十分やぞ D&D用のショトカも作れるしな
>>175 「のようなファイルがあるときに」の条件がどこまでかわからないが
>>176 が一番早いのは間違いない
set "a=あああ_" set "b=.flv" setlocal enabledelayedexpansion for /L %%i in (1,1,99) do set /a c=%%i+1000 & ren "!a!%%i!b!" "!a!!c:~1!!b!"
>>175 pushd "%~dp1"
:LOOP
for /f "tokens=1,2 delims=_" %%a in ("%~n1") do (
set FNAME=%%a
set /a FN=%%b+1000
)
ren "%~1" "%FNAME%_%FN:~-3%%~x1"
shift
if not "%~1"=="" goto :LOOP
>>180 変換の数字の前が_文字じゃないかもしれないし
_文字がファイル名の中に混じっている可能性もあるし
どのスレでも一緒だが質問の要件が分かりにくいのはめんどうだな
なんでか知らないけど他人に勝手にマルチポストされたけど
>>175 の質問は元のスレで解決したのでもういいです
cd \ pushd D:\abc setlocal popd としても元の \ に戻らなかった
>>184 そうならなきゃ逆にダメでしょ
setlocalでは(親の環境を引き継いだ)別の環境の上で実行されている
カレントを移動しようが環境変数を操作しようが元の環境には影響しない
pushd D:\abc
setlocal
endlocal
popd
または
setlocal
pushd D:\abc
endlocal
>>185 ありがとうございました
そういうことでしたか
今さらバッチファイル入門て…
余計な被害者増やさずPowerShellにしろよ
これだからIT後進国は
超入門コマンドプロンプト:バッチコマンドで定型処理を行う (1/3) - @IT
http://www.atmarkit.co.jp/ait/articles/1709/15/news034.html 017年09月15日 05時00分 公開
>>187 このスレのタイトル見てから言えよ
それとも、お前は、自分が使ってないソフトのスレ行って
「別のソフト使え」って言って巡るのが趣味なのか?
PowerShellに移行しようと思ったこともあるけどファイルをD&D出来ないから断念した あと他人の環境で動くのか分からないから渡しにくいし
まあbatに面倒臭いとこがあるのも理解できるけど せめて正規表現と小数の計算くらいはあればよかったんだが
自分で使うにはPoweShellはめちゃめちゃ便利だけど 一般的に定着してるかというとそうじゃないし
PowerShell は起動が遅いから小さいバッチをループで呼び出すのには向いてないんじゃないかな。 いったんロードしたオブジェクトを関数形式で呼び出せばいいんだろうけどよくわからなくてめんどくさいし。
最近、フリーソフトとかの小さいやつの管理がめんどくさくなって メニュー代わりにバッチファイルを使うことにしたんですよ。 全部をVHDに入れてマウントなんで、持ち運びは仮想ディスクファイル1個をコピーするだけ。 起動が素早いのがメリット。 アイコンが出ないのがデメリット。 アイコン出そうと思ったら全環境で共通のドライブ名に固定してショートカットを使ったらいいと思うけど。 プログラムの入ったフォルダ Program Files 3 バッチファイルの入ったフォルダ Program Link [FirefoxPortable.bat] set pathname1=%~d0\Program Files 3\FireFoxPortable52.0.2\FirefoxPortable\FirefoxPortable.exe start "" "%pathname1%"
それだけならバッチ作るまでもなくハードリンクにすればアイコン問題も解決では
あ、すまんそれだと実行ファイルと同じフォルダのDLL読めないからダメか
短いファイル名に関していくつか質問 1 短いファイル名はダブルクオーテーションで囲まなくても実行可能? 2 短いファイル名は取得して一ヶ月経っても変動せずにそのパスを実行出来る?
>>196 「1」は、多分可能
「2」は、他にファイルが出来なければが前提かと
「dir c:\*1」と「dir c:\*1 /x」を実行して挙動を確かめて下さい。
少なくともNTFSではファイルの情報としてショートファイルネームも格納されるから ファイルが存在したままある日突然名前が変わることはないはず そのファイルを削除して似たようなロングファイルネームの別のファイルを作った時 同名だけど別のファイルが出来てしまう事はありえる
レスありがとうございます。
ちなみに自分がやりたかったのは↓と同じケースで自作のbatをタスクスケジューラに登録したいというものでした。
schtasksで半角スペースを含むパスを実行させたい (DOSプロンプト活用相談室LOG)
http://fpcu.on.coocan.jp/dosvcmd/bbs/log/taskkillstart/at/4-0842.html "を\"と書いてエスケープさせるやり方もあるようですがそちらではbatにダブルクォーテーションで囲った引数を渡すと不可解な動作をすることがあり上手くいきせんでした。
batのパスにスペースを含んだ場合 起動しない
batのパスにスペースを含まない場合 %~dp0を実行したときにbatのフォルダパスの頭にカレントディレクトリの文字列も追加される
mklinkやsubstを使って違う名前でアクセスするのはどうなのでしょう うまくいくかどうかわかりませんが ファイル名フォルダ名に空白や%^!みたいな記号があると困ることが多いですね
>>199 この書き方に準じていないだけでは?
A Scheduled Task Does Not Run When You Use Schtasks.exe to Create It and When the Path of the Scheduled Task Contains a Space
https://support.microsoft.com/en-us/help/823093/a-scheduled-task-does-not-run-when-you-use-schtasks-exe-to-create-it-a Schtasks.exe を使用して、スケジュールされたタスクのパスにスペースが含まれている場合を作成するときにスケジュールされたタスクが実行されません。
https://support.microsoft.com/ja-jp/help/823093/a-scheduled-task-does-not-run-when-you-use-schtasks-exe-to-create-it-a 失敗例
schtasks /create /tn "my task" /tr "c:\foldername containing spaces\script.bat arguments" /sc once /sd 07/29/2003 /st 10:01
成功例
schtasks /create /tn "my task" /tr "\"c:\foldername name containing spaces\script.bat\" arguments" /sc once /sd 07/29/2003 /st 10:01
>>201 自分の説明が下手で伝わらなかったんだと思いますが、成功例の方の記述でパスにスペースを含むbatは起動できるのですがそのbatにダブルクオーテーションを含む引数を渡すと動作がおかしくなるのです。
引数にダブルクオーテーションを含まない場合は正常に起動できます。
一応追記しておくと、おかしくなるのはタスクスケジューラから起動した場合限定で通常の起動では問題ありません。 呼び出すbat内の記述にミスがあるとかそういうのではないと思います。
argumentにダブルクォーテションがある場合もパスと同様に\"してる?
基本的に引数の中の半角スペースはデリミタであり そこより左に " が奇数個あればデリミタじゃなくなる それに関しては \" とか ^" とかあっても関係ないんじゃね
>>207 もう見てないかも知れないけど
schtasks /create /tn "test\test" /sc once /st 23:00 /tr "cmd /s /c \"\"C:\schtasks test\schtaskstest.bat\" hoge1 hoge2 \"ho ge3\" \"h oge4\"\""
これだと実行ファイルのパスにスペースがあっても問題ない
>>209 なるほど、直接batを登録するのではなくてcmdのほうを登録すれば良かったんですね
思いつきませんでした
助かりました、ありがとうございます
文字コードがUTF8のテキストファイルが2つあるのですが FCコマンドで差分を出力したところ文字化けしてしまいました。 何か良い方法はないでしょうか?
なんでSJISなんだよ、unicodeにすればいいじゃん(Windows2000,XPは除く) @echo off set f1=%1 set f2=%2 if not defined f2 echo 引数1.2に比較するファイルパスを指定してください& goto :eof if not exist %f1% echo ファイル %1 がありません& goto :eof if not exist %f2% echo ファイル %2 がありません& goto :eof start "" /min /wait cmd /u /c "chcp 65001 & type %1>u_%1 & type %2>u_%2" chcp 932>nul fc /u /n u_%1 u_%2 del u_%1 u_%2
start付けるとうまくいかないな 訂正 start "" /min /wait cmd /c "chcp 65001&cmd /u /c type %1>u_%1&cmd /u /c type %2>u_%2" fc /u /n u_%1 u_%2
バッチファイル作っておいて以下のようなフォルダの名前の変更を毎回ダブルクリック一発で済ませたいのですが いろいろやってみたのですが、というほどの力もなく お知恵お貸し下さい 処理前のフォルダ名一覧 1008安住紳一郎の日曜天国 10月15日安住紳一郎の日曜天国 10月15日爆笑問題の日曜サンデー (1) 10月15日爆笑問題の日曜サンデー (2) 処理後のフォルダ名 1008安住紳一郎の日曜天国 1015安住紳一郎の日曜天国 1015爆笑問題の日曜サンデー (1) 1015爆笑問題の日曜サンデー (2)
>>215 for /f "delims=" %%a in ('dir /ad /b ^| findstr /b /r "[0-9][0-9]月[0-9][0-9]日"') do call :SUB "%%~a"
exit /b
:SUB
set s=%~1
ren %1 "%s:~0,2%%s:~3,2%%s:~6%"
>>216 ヒント下さったようでありがとうございます。でも、ゼロから書き始めることが出来ないんです。
>>217 私の求めていた動作です。これで完璧、ありがとうございます
ひと安心して解析に移ったわけです。。。
1.
"[0-9][0-9]月[0-9][0-9]日"
↑これでは22月33日にも対応というわけか、こやつめハハハ
フォルダ名の行頭部分は日付として機械的に生成される予想できる値ですので[0-9]で何の問題もないです。
勉強の為に、ここをいじってみました。
Month部分は、1 2 3...10 11 12、なら[1-12]で済むのかな。
ところが0埋めなので、01 02 03...10 11 12、となると、0[1-9]|1[0-2]、かな。
Day部分は、01 02 03...29 30 31、うーん0[1-9]|[1-2][0-9]|3[0-1]、となる。
これらを書き換えてみて、はい、動きませんでした。
今回のような自分用プログラムは動けばよいわけで、教えて下さった[0-9]で何の問題もない。
これ以上無駄な時間を掛けても&シンプルな方が可読性がよい
2. for a in ('標準出力 パイプ 標準入力') do この部分、パイプの縦棒の左にくっついてる^は何者なのでしょう。。。初めて見ました。 アッ、日付部分が行頭だからか?いやfindstrに行頭オプションの/Bが付いてるし、そもそもパイプの左になぜ? 検索してみたのですがわからずここで冷や汗が出てきて ウーンこれはなんなんだろう。そもそもメタ文字なのか銅貨さえわからない。 3. そもそも何をしているのかというとradikoというプログラムでお気に入りのラジオ番組を録音しています。 AMラジオ番組ではCMのほとんどが過払い金のCMで聞きたくないのでスキップしたいのです。 ウォークマンで右ボタンを長押しすると早送り再生になるのですが、突然入るCMにイラッときて 長押しではなく短く押してしまって次のmp3ファイルに飛んでしまうのです。イライラッ! そこで1分ごとに分割してしまうことにしました。mp3directcutというソフトを使って切り出すことが出来ることを 知りました。そのうち、切り出し作業が面倒になって調べていくうちにコマンドラインでの実行も可能と分かり、 バッチファイル化の作業に掛かりました。出来上がったのは以下のような4行のバッチファイルです。 @echo on echo %* for /D %%a in (%*) do (mkdir "%%~na")&(copy 1min.mpd "%%~na".mpd)&(mp3directcut "%%~fa" /autocue "%~dp1%%~na")&(del "%%~fa")&(del "%%~na".mpd) pause 1min.mpdというのは1分ごとに切る指定が記述されているキューファイルです。同名の.mpdファイルがあるとそれを使ってくれるみたいなので、最初に元ファイルとして作っておきます。 1分ごとに切り分けられたものを再生してもけっこう大丈夫で、音楽だと気付く程度です。 いろいろ書いてしまいましたが頭が精一杯なのでとりあえずお礼申し上げ失礼ます
>>219 ^(キャレット)はエスケープ文字
これを付けずに実行すると、コマンドラインパーサで式評価時にパイプとして機能しちゃう
つまりfor文の途中にパイプが現れてそこで途切れちゃうことになる
やりたいことは、この行の最初の評価時には単なる|の文字として取り扱ってもらい
次の''で括ったコマンドの評価時にはパイプとして機能してほしいってわけ
1回の評価を→で表すとすると、
^| → |
^^| → ^| → |
^^^^| → ^^| → ^| → |
って感じに展開されていく(俺は3回まで使ったことがある)
%a%とかの環境変数の評価も似たようなもんだね
%%a%% → %a%
環境変数の評価を遅延させる方法はつまり %%temp%%と%^temp%との2通り書けるわけだ (結果的に同じになるけど動作は違う)
>>221 これはコマンドプロンプトでのことでbatに書くときはダメだね
評価と展開がごっちゃになってる 俺の理解が浅い(忘れっぽい)せいだな
ここで言ってる遅延と、いわゆる「遅延展開」は別物ですか?
>>218 >Month部分は、1 2 3...10 11 12、なら[1-12]
[]は文字集合。[]内の文字のうち何れか1文字という意味。文字列は扱えない
[1-12]だと"1-1"と"2"という意味で1か2になる
01-12月、01-31日を表すのなら [01][0-9]月[0-3][0-9]日
[01]が0か1で十の位、[0-9]が0から9で一の位
桁の揃っている01なら可能だが1-12月はfindstrの貧弱な正規表現では1度に表すのは無理なので
1桁の場合と2桁の場合とを別けて検索文字列に設定する必要がある
ちょ、誰か
findstr /r "検索文字列" とfindstr /r /c:"検索文字列" の違いを教えてくれ。忘れた
>>225 解説ありがとうございます
とりあえず日付の所いろいろやってみてるのですがうまく行かないままです。
正規表現といわず直接文字列を指定して | が有効になるかどうかというところから実験してます。
for /f "delims=" %%a in ('dir /ad /b ^| findstr /b /r ""10月15日"|"10月16日""') do call :SUB "%%~a"
pause
exit /b
:SUB
rem set s=%~1
rem ren %1 "%s:~0,2%%s:~3,2%%s:~6%"
findstrについての解説は検索で出てきた
http://www.atmarkit.co.jp/ait/articles/0412/18/news018.html を読みました。読んだだけです。頑張ります
>""10月15日"|"10月16日"" "で""を囲えないしfindstrの正規表現で|は使えない findstr /? まともな正規表現を使いたければvbsやPowerShell、Perlとか別のスクリプトに行ったほうがいい バッチだと"&"や"%"とかダメ文字があるし凝った事をやろうとするといずれ行き詰まる 急がば回れ
参考にWSHでもどうぞ(hoge.jsファイルとして作成)、コマンドプロンプトから hoge "フォルダ名" (又は cscript //nologo hoge.js "フォルダ名") 又は、エクスプローラ等からフォルダをこのjsファイル(又はショートカット)にドロップして実行 var fso = new ActiveXObject("Scripting.FileSystemObject"); var args = WScript.Arguments; if(args.length<1) throw Error("引数にフォルダを指定してください"); if(!fso.FolderExists(args(0))) throw Error("指定のフォルダが存在しません"); var folder = fso.GetFolder(args(0)), s = "", success = [], fail = [], name, name2, em, i, r; var re = /^(\d{1,2})月(\d{1,2})日(.*)$/; var func_new_name = function(all,mm,dd,ss) { if(mm<1 || mm>12 || dd<1 || dd>31) return ""; return ("0"+mm).substr(mm.length-1) + ("0"+dd).substr(dd.length-1) + ss; }; em = new Enumerator(folder.SubFolders); for(em.moveFirst();!em.atEnd();em.moveNext()) { name = em.item().Name; if(re.test(name)) { name2 = name.replace(re,func_new_name); if(name2) { try{em.item().Name = name2; success.push(" "+name+" -> "+name2);} catch(e) {fail.push(" "+name+" -> "+name2);} } } } if(success.length>0) s = "リネーム成功\n"+success.join("\n"); if(fail.length>0) s += "\nリネーム失敗\n"+fail.join("\n"); WScript.Echo(s || "対象フォルダなし");
もうPowerShellのRename-Item使おうぜ 個人用途だろうし制約ないでしょ
覚えたてによく居るよね 要件無視した勝手な仕様でエラー判定とか結果ダイアログとかゴテゴテ実装してドヤ顔で持ってきちゃう子
まあダブルクリックで不意に実行されちゃうようなのは作りたくないよな
>>215 無理やりバッチファイルの例
for /d %%i in (*) do set "a=%%~nxi" & call :w
goto :eof
:w
setlocal enabledelayedexpansion
set "e=m" & set /a b=0,m=0,d=0
:x
set "c=!a:~%b%,1!"
if not defined c goto :eof
for /L %%j in (0,1,9) do if "!c!"=="%%j" set /a !e!=!e!*10+c & goto y
if not "!c!"=="月" goto z
if not "!e!"=="m" goto :eof
if !m! gtr 12 goto :eof
set "e=d"
:y
set /a b+=1 & goto x
:z
if not "!c!"=="日" goto :eof
if not "!e!"=="d" goto :eof
if !d! gtr 31 goto :eof
set /a f=m*d,m+=100,d+=100,b+=1
if !f! gtr 0 ren "!a!" "!m:~1!!d:~1!!a:~%b%!"
>>231 うちの現場のバッチは例え内部で使わなかろうが最低1つは必ず引数を渡す仕様になってる。
そしてそれが渡されなかった場合は処理せずに終了する作りになっている。
理由は誤ってダブクリしちゃった場合の対策なんだってさ。
>>230 なんか癇に障ったみたいだけど、言い訳すると
俺は、質問者によって回答内容を変えてる
今回の質問者は初心者だと感じたし、さらには細かい拘りを持っているように見受けられた
(13月32日なんて作らないだろうし、もしあったって1332に変換されて悪いことはないと思う)
色々と手を加えて試行錯誤することが好きなんだろうなって思ったから
役に立ちそうな追加部分を記述した
それに1レスで書く分には、数行増えようが関係ないだろうと思ったしね
キッティングの自動化をしたいんだが、参考になるサイトない?
一発で、ファイアウォールの受信規則とかインターネットオプションとか
>>215 $before = ls -Directory | Where-Object { $_ -match "^\d+月\d+日" }
$after = $before | foreach { $_.Name -replace '^(\d+)月(\d+)日', '$1$2' }
$idx = 0;
$before | foreach {
Rename-Item -WhatIf $_.FullName $after[$idx];
$idx++;
}
PowerShell で書いたので、cd で、そのフォルダへ移動して実行して。
-WhatIf が付いているので、本当には実行せずに、結果だけを見れる。
本当に実行する際は、-WhatIf を削除して実行して
配列 $before には「02月03日」などで始まるフォルダだけを、入れる。
配列 $after には「02月03日」の部分だけを「0203」に変換した、フォルダ名を入れる
Rename-Item で、該当する全フォルダ名を変換する
問題は、月を01~12まで、日を01~31までのチェックを入れることだけどね
>>244 ls <directory-name> -directory | ren -newname {$_.name -replace '^(¥d+)月(¥d+)日', '$1$2' }
lsの-filterやwhere-object使ってもいいけど
この例の場合は不要だと思うよ
ls -directory | ren -WhatIf -newname {$_.name -replace '^(\d+)月(\d+)日', '$1$2' } 上記で、where-object が無いと、 変更されないフォルダまで、表示されるのが気持ち悪い
Windows7SP1では、Get-ChildItemに-directoryオプションは無いんでエラーが表示された 調べたら、3.0以降でこのオプションが付いた模様 この際なので、5.0,5.1をインストールした Windows7の人の参考まで
PowerShellのスクリプトファイルの拡張子は普通.ps1を使うが
デフォルトではファイルの実行を許可してないし、
また許可後もダイレクトにファイル名を指定しても実行できない
って保険かけすぎで入門者には敷居が高いだろと思わないでもないなあ
>>247 where-objectを入れてみた
(まだ2時間ぐらいしかやってないんでもっといい書き方があるかも)
$re='^(\d+)月(\d+)日';ls -directory|? name -match $re|ren -whatif -newname {$_.name -replace $re,'$1$2'}
このスレ的にはアリアス使うなら、lsよりもdirが合ってる気もするけど
ここで聞くべきか迷ったのですが… 自分のマシンからリモートデスクトップで接続できるサーバー(確かWin2008R2)があって そのサーバーと同じネットワーク内にクライアント端末(Win7)があります。 そのクライアント端末のプロセスをリモートデスクトップで接続したサーバーから確認することは可能でしょうか? (サーバーには管理者権限で接続しています) 要はクライアント端末でtasklistコマンドを打った結果が見たいのですが。 ちなみにクライアント端末はDHCP設定なので起動のたびにIPアドレスが変わります… 今は1日に何度も遠くにあるクライアント端末まで行ってプロセスを確認しています。 1回だけ行ってIPアドレスをメモるぐらいなら全然構わないので何か方法があれば教えて下さい。
クライアントに自分のタスクリストをファイルを記録する周期ジョブを作成しておく 必要であれば暗号化しておく そのファイルをメールで自動送付するようにしておくか、 クライアントにwebエリアがあればそこに置きこちらから見にいく
>>250 サーバから tasklist /s クライアント端末名 (/u user /p pass) を実行では見れないんですか?
ファイアウォールの設定が必要かもしれませんけど。
>>250 1) 他のPCのプロセス状態を知りたい
2) DHCPで設定されているPCのIPアドレスを知りたい
ってことでいいかな
1) はtasklist の /s オプションで知りたいPCのIPアドレスを指定すれば行けるはず
ただし事前にPC側に設定が必要
かつPCにログインできる情報が必要
2) は
2-1) 直接見に行ってipconfigで確認する
2-2) MACアドレスわかってるならサーバーからそのネットワークアドレス全体にpingを打ちつつarpコマンドで相手のMACアドレス確認していけばいい
2-3) DHCPサーバーを管理してるならPCのIPアドレスを確認する方法があるかも、まあそれならPCのIPアドレスを固定した方がいいかも
2-4)
>>251 みたいな方法で定期的にIPアドレスを通知してもらう
みなさん情報ありがとうございます。
来週になったらとりあえず
>>252 さんの方法を試してみます。(一番手軽なので…汗)
それでダメな場合は一日一回直接IPアドレスを確認しにいく方式にします。
というのもpingのブロードキャストは現場のルールで禁止されてるっぽいので。
クライアント端末も特別な用途のためのものなのでタスク作ったり何かを仕掛けるのは厳しそうです。
仕掛けられれば業務はすごく楽になるんですけど「セキュリティ上問題が…」とか言われて突っぱねられる可能性大です。><
尚、pingブロードキャスト以外の方法でIPを知る方法については自分でも調べてみます。
どうもありがとうございます。助かりました!
>>254 >>252-253 に書いてあるけど事前にクライアント側の設定しないとtasklist /sでプロセス情報見れないけど、そこは大丈夫なの?
set infilenm=001.txt set outfilenm=002.txt set beforestr="""" set afterstr="" type nul >%outfilenm% setlocal enabledelayedexpansion for /f "delims=" %%A in (%infilenm%) do ( set line=%%A echo !line:%beforestr%=%afterstr%!>>%outfilenm% ) endlocal 001.txtからダブルクォーテーションを削除して002.txtに保存したいだけなんですが、 3行目と4行目の表記がわからず、考えられる限り書き直して、うまくいきません。 あるいは別のBATでもいいのですが教えてください。
>>256 set beforestr=^^"
set afterstr=^^
でどうかな?
ただ001.txtのデータ次第でうまくいかない場合があるんで 別のスクリプト言語(PowerShellやWSH等)で書いたほうがいい
>>257 >>258 素早いお答えありがとうございます。
>>257 >set beforestr=^^"
>set afterstr=^^
ダブルクォーテーション消えました!
ありがとうございました。
>>259 どういうことに使うのか知らないけど、大切なデータなら止めとくべき
改行だけの行が消えるのは知ってると思うけど以下のような行があると(回避は可能だが)
ab!cd!ef
a! "b ^
>>260 ご心配ありがとうございます。
大丈夫です。ものは、<a href とかのhtmlタグで作成したリンクリストで、
正規表現とかエスケープっぽい記号等はなく、
そもそもプライベートファイルなので、これで素早くリストができて万々歳です。
>>260 これじゃダメか?
ていうかダメな例を教えてほしい
for /f "delims=" %%i in (1.txt) do (
set a=%%i
setlocal enabledelayedexpansion
echo !a:^"=!
>>2 .txt
endlocal
)
バッチファイルに渡された引数が1つなのか2つなのかを判定したいのですが どのように記述すれば良いのでしょうか? 以下ではダメでした。 if defined %2 echo 引数は2つです else echo 引数は1つです
>>264 ありがとう
for /f "delims=" %%i in (001.txt) do (
set "a=%%i"
setlocal enabledelayedexpansion
set "a=!a:"=!"
echo.!a!>>002.txt
endlocal
)
これで空行以外は完璧かな?
>>262 の奴で
"echo "を"echo."にするとダメなのに"echo,"にするとOKなのは何故なんだぜ?
今まで、ピリオドとカンマ、セミコロンに違いがあるとは思ってなかったから
ずっとピリオド使ってたのに
>>267 "eol=" を指定しないと行頭文字が ; だと読み飛ばす
"delims=" を指定しないと行頭の空白が無くなる
両方同時に指定する方法はあるのか?
>>268 「,」「;」「=」は特別区切り文字だから。
例えば、C:\直下に「a」ってフォルダ作って
「b.cmd」
for /f %%a in ('echo,b') do echo,%%a
「b b.cmd」
echo;c %1
pause
のバッチ作成して、コマンドプロンプトで「C:\a」に移動してから
「b.cmd」を実行すると、()の中の「,」が消えた状態で表示される
「b b.cmd」を実行すると、「b.cmd」が実行される
「"b b.cmd"」を実行すると、「b b.cmd」が実行される
今度はファイル名を指定して実行で
cmd /c "C:\a\b b.cmd"
cmd /c "C:\a\b b.cmd" dを実行すると、pauseで止まるけど
cmd /c "C:\a\b b.cmd" "d"を実行すると、一瞬で終わる
cmd /c,"C:\a\b b.cmd" "d"なら動く
結構知られていないんだよね。
>>270 ありがとう。完全に動作しました
そもそも eol の既定値が ; だとかヘルプに書いてないぞ
ちなみに "eol=" とすると eol が空になるのかと思ったら
今度は行頭に " があると読み飛ばすようです
何なんだ、これは。for 文のバグですかね
@echo off prompt $g set a=/? set b=exe set c= off echo on echo,%a% echo;%a% echo.%a% echo.%b% echo.%c% echo pause
一時的なwindows資格情報の付与 付与→(再起動)→ポップアップを閉じるまで作業→(再起動) の流れをバッチ実行一発で済ませたいと思ってる。 (○.bat) cmdkey 書き込み copy **.batを配置 schtasks 再起動後のタスク登録(**.bat実行) shutdown 再起動 ↓ (ログイン) (**.bat) echoでmsgbox表示(閉じるまで待つ) cmdkey /delete ←ここで資格情報が消えない schtasks /Delete タスク消去 del /f "%~dp0 自己消去 タスクは一応highest タスク実行だとcmdkey通らないとかある? bat素人で何が原因で消えないのかわからない・・・ ポップアップ表示中にcmd開いてcmdkey打つとちゃんと消える
回りくどい方法ですが自己解決できました。 .vbsにcmdkey /deleteを入れ cmdの管理者権限起動用ショートカットを作成 schtasks からhighestをぬいて、管理者権限でcmdを再起動 vbsを実行で資格情報を消すことができました。
copy /b 1.mp4+2.mp4 3.mp4 上記で結合した3.mp4の動画に2.mp4の内容が追加されないのですがなぜかわかりますか? 3.mp4のファイルサイズだけは1.mp4+2.mp4の容量になっています すぐ出来ると思ったのにつまづいた泣
>>277 ちゃんと結合されている
バイナリで結合してフォーマットが1.mp4の分しかないだけ
コマンドプロンプトでなく動画フォーマットの勉強しろ
動画形式の勉強など、自分でやるものじゃない 動画編集アプリを使うべき
今の編集アプリだとmp4再エンコしなくてもそのまま繋げられるのかな?
>>280 バッチから結合を指示できる動画編集アプリよろしくね
64bitOS環境 バッチ1つでWOW64内のcmdで実行する方法ってありますか?
呼び出し元バッチに戻る終了方法を追加してほしい exit /B だとcmdを終わるだけ戻らない call で呼び出さなくても戻る機能をつけてほしい exit /r や return文で
ダウンロードしたローカルアプリ(Jane Styleなど)が
重要な場所のローカルファイルから情報を盗もうとしてないかどうか念のため監視したいのですが、
https://technet.microsoft.com/ja-jp/sysinternals/handle.aspx このdosで使える handle は出力ファイル名の日本語が文字化けするんですが、何かいい方法ないですか?
文字化け以外に関しては非常に便利です
出力をdosで加工してエクスプローラーのログを除外して、ユーザー+プロセス+ファイル名が初登場の時だけ出力してます
これでもし見慣れないファイルアクセスがあったら目立ちます(GUI系はリアルタイムで消えるので)
ファイル名のようなシステム要件には、半角英数字だけを使う。 半角空白も使うな。Mac でバグる すべてのアプリの開発者が、多国語のファイル名では、テストしていないから、 多くのアプリでバグる 特に、書庫を使う、圧縮解凍アプリでバグる
echo. で空行を表示できると知りましたが この「.」には何の意味があるのでしょうか?
>>291 意味を考えてはいけません。調べてませんが、英語のピリオドなので文字列なしで終わりという意味合いからそうしたのでしょう。
echoの直後の文字列は出力されないんだっけ? 「.」の以外の文字列でも空行になるけど1番問題が起きにくいとかそんなのかな
ちょっと前にその辺の話が出てた
>>264-274 特別区切り文字というものがあるなんてここで初めて知ったんだけど…(本当かどうかはまだ確かめていない)。 もはや紙媒体で信用できる会社からの体形的な出版物が無いのよね。 …ある??
こんなのは仕様じゃなくて実装上の結果にすぎない undocumennt specと言ってもいいが、正式な本に仕様として載るようなもんじゃないと思う
>>296 そりゃ分かるんだけど…。
UNIX の bash だっておかしいところが結構あってさ。
でも「構文解析が未熟な時代、全てを(記号ですら)コマンドだと置いた結果」という説明の仕方ができるそうな。
C言語の仕様だっていい加減後付けが多い。でも説明を試みた結果がANSI。無理が多いけど。
Windows界隈ってそういうのが貧しいと思う。
スレ違いだけど、PowerShell も Core とか言い出してからなんかおかしくないか?
>>297 特別区切り文字という言葉はアレだけど
cmd /? で表示されるヘルプの最終行に
=;, は特別な文字として列挙されてますよ。
>>297 要はさんざん検証して挙動を確認しないと恐くて使えないってこったなw
関係ない話ですまんが いまだに cmd /? の表示が変だな、一部重複してる マイクロソフトは直す気が無いのか たぶんNTの頃から変なんだが
バグレポートに誰も上げていないか、 あるいは上げられていても優先順位がものすごく低いのでしょう。
>>302 非成長分野、非収益持ち出し分野とみなされて、最低限の人数しかいないのでは
おまけに優秀なのは来ない
優秀な奴はさらっと変更して賞賛されるけど、 そうじゃない奴がさらっと変更すると、 勝手なことすんなって怒られるんだよな。
bash が最近のプロダクトだとか…ヨボヨボの痴呆が入ったおじいちゃんか?
UNIX で bash が出たのって 20世紀なんだが。
>>299 これのことか?明らかに違う。
> 引用符が必要な特別な文字は次のとおりです:
> <スペース>
> &()[]{}^=;!'+,`~
>>300 自分が新規で書けるなら VBScript でいい。
「これは例外、あれも例外、それも例外」なブツなんか触りたくない。
そんな時間があるなら生産的な言語に費やしたい。
触らざるを得ないからイラつく。阿呆か。
PowerShell は Windows の自動化から管理系を抜き出した方向に行こうとしているので何だかねぇ…
>>305 GNU後の新造品じゃねーか。モダンもいいところだろ。
歴史を知らないバカとは話が出来ないってのは本当だな。
今時VBScriptとか言ってる老害の相手するなよ...
年寄りのくせにGNU前を知らないんだとしたら、死んだ方がいいね。
VBScriptは依然として結構イケると思うけどな
>>301-302 コマンドのバグ ⇒ 全世界のユーザーに影響出るから下手に直せない コマンドのヘルプの文言誤り ⇒ 優先度低いのでなかなか直さない ってことかなるほど。 >>313 cscriptで自身を実行する外見バッチ中身WSHみたいなんもあるにはあるし…
>>313 元を辿ってみると、
>>297 が話を逸らしたせいだ
そこからどんどん逸れてvbに行き着いた
>>315 batに埋め込めるのはjscript(条件コンパイルの構文がbatとうまい具合にかみ合った)だけでvbscriptは無理
>>317 wsfの手があったか、あとjsでもスクリプトエンコードで書けばなんとかなるね
powershellで似たような事はできませんか? 1ファイルにしたくて
>>319 【最強CUI】PowerShell -Part 2 [無断転載禁止]©2ch.net
http://2chb.net/r/tech/1480109402/ どうしても分からないので質問致します。
@echo off
@rem バッチファイルのディレクトリに移動
cd /d %~d0%~p0
set USR_INPUT_STR1=
https://www.openrec.tv/live/fKGMub0cd6j @rem 引数有無と引数名チェック
if "%USR_INPUT_STR1%"=="" goto ERROR
echo;%USR_INPUT_STR1%|findstr /R /C:"^http" /C:"openrec" >NUL||(echo "%1" を処理できません) && goto ERROR
@rem URLのアドレスとHTMLを環境変数へ設定
set ADDR=%USR_INPUT_STR1%
for %%I in (%USR_INPUT_STR1%) do set HTML=%%~nxI
@rem HTMLダウンロード
curl -L --max-redirs 10 -R -O %ADDR%
if not %ERRORLEVEL%==0 goto ERROR
@rem Shift-JISに文字コード変換
nkf -s --overwrite %HTML%
set TARGET=%TARGET:playlist=chunklist%
@rem ffmpegで動画吸い出し
ffmpeg -c copy "%TITLE%.ts" -i "%TARGET%"
@rem 最後にcurlで出力したソースファイルを削除
@rem for /R %%f in (*.) do del /Q "%%f"
pause
exit
:ERROR
echo 引数が無効のため処理できませんでした
pause
exit
このようなbatファイルを作ったのですが、どうしても最後に
sourcefile=
https://station303.openrec.tv/live1/667d4bef5cb4af8db6b9198cab7b3148e957e477/chunklist.m3u8: Invalid argument
と無効な引数と言われてしまい動画の吸い出しが出来ません
完全に手詰まりなため、丸投げにはなってしまいますがご教授いただければと思います
よろしくお願いします
>>322 とりあえず最初の行を
rem @echo off
にしてどこでエラーになってのか確認しろよ
>>322 これ途中の処理抜けてない?
TARGETにURLが入らないんだけど
170のやつを適当に書き直したら動いたよ for /F tokens^=2^ delims^=^" %%I in ('type %HTML%^|find /I "data-sourcefile"') do set "TARGET=%%~I"
>>322 の最初が抜けてました・・・
@rem HTMLから文字列抽出
for /F "tokens=2 delims=<>| " %%I in ('type %HTML%^|findstr /R /C:"<title>"') do set TITLE=%%~I
for /F "tokens=* delims=data-file= " %%I in ('type %HTML%^|find /I "playlist.m3u8"') do set TARGET=%%~I
>>325 ありがとうございます・・・
エラーを見たのですが、なぜかsourcefile=が付いてしまっていました
何度もありがとうございます
echo abc 1>x1 1>x11 2>x2 3>x3 とするとDOS窓が応答しなくなった x11 x2 x3 ファイルができるが x1ファイルはできない
compフォルダ配下にはa,b,c,…ってフォルダがあって、 そのフォルダの中にはzipとrarの圧縮ファイルがある compopenってフォルダを作って、compの中のフォルダ階層は変えないで、compopenフォルダ内のaやb,cのフォルダにそれぞれすべて展開させたいときってどうするの? zipやrar毎にフォルダ作って展開させたい D:/ ├comp/ │ └ a/ │ └ 111.zip │ └ 222.zip │ └ b/ │ └ xx1.rar │ └ xx2.rar │ └ c/ │ └ ttt.zip │ └ rrr.rar D:/ ├compopen/ │ └ a/ │ └ 111/ │ └ 222/ │ └ b/ │ └ xx1/ │ └ xx2/ │ └ c/ │ └ ttt/ │ └ rrr/
>>329 >>12-19 の方法で相対パスを取得すれば出来ると思うよ
自分用に書いたbatを流用してみた
多分こんな感じで動くはず
https://pastebin.com/zEpvpdCa >>329 set "a=D:\comp" & set "b=D:\compopen"
setlocal enabledelayedexpansion
for /L %%i in (4,1,1000) do if "!a:~%%i,1!"=="" set "c=%%i" & goto x
:x
endlocal & set "c=%c%"
for /r "%a%" %%i in (*.zip *.rar) do set "d=%%~dpni" & set "e=%%~i" & call :y
goto :eof
:y
setlocal enabledelayedexpansion
7z x -o"!b!!d:~%c%!" "!e!"
>>332 なるほど
自分のは冗長に書きすぎてたね
>>329 使い回しあんまり考えなければ
-------- ここから
set path=C:\Program Files\7-Zip;%path%
cd /d D:\comp
for /f "usebackq delims=" %%i in (`dir /ad /s /b`) do (
echo,"%%~i"
set "tmppath0=%%~i"
call set "tmppath1=D:\compopen%%tmppath0:~7%%"
pushd "%%~i"
call 7z.exe x *.* -spe -bso0 -o"%%tmppath1%%\*" 2>>D:\compopen\errlog.txt
popd
)
-------- ここまで
マズいフォルダ(パス)名が無いことを前提に、もろもろ 7-Zip に良きにはからってもらう
>>332 >>334 ありがとうございます! 150GBくらいあるから、まだ展開し終えてないけど、 動き出しました。 実際のcompの中のa,b,c,・・・フォルダの中のzipやrarの名前は、 今のところ、下記みたいにフォルダの文字列含んでて、階層を上にしてもよかったかなと思いつつ、 例外も出てくるかもしれないので、このまま走らせてみます。 しっかり解凍しだしてフォルダ生成してくれてます。 D:/ ├comp/ │ └ a/ │ └ a111.zip │ └ a222.zip │ └ b/ │ └ xx1b.rar │ └ xx2b.rar │ └ c/ │ └ cttt.zip │ └ crrr.rar そもそも、そんな複雑な手続きには、PowerShell, Ruby などを使えw
コマンドプロンプトの仕様についてだけど、遅延展開ってデフォでONじゃダメだったのかな? あれ打ち込むのマンドクサ('A`)
1.test.exeという実行ファイルがある。 2.test.exeのフルパスは必要に応じて「test.exeをShift+右クリック」→「パスをコピー」して変数testExeに格納してもらう。 このフルパスには"D:\a bc\test.exe"のように空白が含まれることがあるとする。 3.FOR文でこのtest.exeを--helpオプションつきで実行し、結果からfindstr&setしたい。 ---作成バッチ--- @echo off cd /d %~dp0 set testExe="D:\a bc\test.exe" FOR /F "tokens=3" %%a IN ('%testExe% --help ^| findstr "TargetStr"') DO ( set kekka=%%a ) @echo %kekka% pause ---実行結果--- 'D:\a' は、内部コマンドまたは外部コマン ド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。 ---解1--- testExeを設定する際、全体をダブルクォートで囲むのではなく、 空白を含むフォルダだけをダブルクォートで囲むようにする。 set testExe=D:\"a bc"\test.exe 解1はtestExeの設定が地味に面倒になってしまうので回避したいのですが、何か良い方法はないでしょうか?
>>338 追記
パスに空白を含む場合も問題ですが、
set testExe="D:\abc\test.exe"
のように空白を含まない場合には
ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
と言われてエラーになるので、それも含めてなんとかしたいという点を書き忘れていました。
「FOR文でフルパスでコマンドを実行したい場合、どうすればよいのでしょう」というのが根本的な質問です。
すみません。
>>338-339 ですが、直接フルパスで実行するのではなくフォルダに移動して実行することで一応解決しました。
---
@echo off
cd /d %~dp0
set testExe="D:\a bc\test.exe"
FOR /F "tokens=1 delims=" %%I IN (%testExe%) DO (
IF "%%~nxI"=="test.exe" (
pushd "%%~dpI"
FOR /F "tokens=3" %%M IN ('.\%%~nxI --help ^| findstr "TargetStr"') DO (
set kekka=%%M
)
popd
)
)
@echo %kekka%
pause
---
問題点や、もっとスマートな方法があれば、教えていただけると助かります。
>>338 @echo off
cd /d %~dp0
set testExe="D:\a bc\test.exe"
for /f "tokens=3" %%a in ('start /wait /b "" %testExe% --help ^| findstr "TargetStr"') DO (
set kekka=%%a
)
@echo %kekka%
pause
>>338 自分もこの問題に直面して同じ解決策とったんだけどこれって何が原因でこうなるの?
こっちのがいいかも 前に似たようなネタがあったような set testExe="D:\a bc\test.exe" for /f "tokens=3" %%a in ('cmd /s /c "%testExe% --help | findstr "TargetStr""') do (
>>341 できました!なるほど、startを使えばよかったのですね・・・。ありがとうございます。
>>342 なんなんでしょうね。仕組みがよくわからないです・・・。どなたか解説を・・・。
やっぱり
>>343 の cmd はダメだな
testExe や TargetStr の中のスペースがデリミタ扱いされる
スペースが2個以上続くと誤動作する
>>341 の start がいい
>>343 >>345 重ねてありがとうございます。
cmdの場合は以下でうまくいくようです。
set testExe="D:\a bc\test.exe"
FOR /F "tokens=3" %%a IN ('cmd /c %testExe% --help ^| findstr "TargetStr"') DO (
やっと思い出したぞ裏技w
前後の端にダミーの二重引用符 ^" を付けるんだった
>>347 のおかげで思い出したぜ
set testExe="D:\a bc\test.exe"
for /f "tokens=3" %%a in ('^"%testexe% --help ^| findstr "targetstr"^"') do (
>>347-348 できました。なるほど、そういう解釈がされるんですね・・・。
バッチってほんと思わぬところでひっかかりますよね。とても勉強になりました。ありがとうございます。
VBでプログラムを作っているのですが、行き詰ってしまったので質問させていただきます。 バッチでiniファイルを読み込み、iniから取得したデータを格納した変数をVBのソース内で使いたいのですが可能ですか? exe形式での納品となるのでiniファイルの読み込みはどうしてもバッチ内で行いたいのです。 ちなみに処理の流れとしては、iniファイル読み込み→exeファイル実行となっています。 どなたかご教授ください。よろしくお願いいたします。
申し訳ございません。 バッチでiniファイルを読み込み、iniから取得したデータを 格納した変数をVBのソース内で使いたいのですが可能ですか? × VBのソース内の変数に格納したいのですが可能ですか? ○ でした。
バッチで、ini ファイルを読み込み、必要な値を取り出して、 それらを引数にして、exe を起動する そして、exe 内では、引数から読み込んだ値を使う
>>352 どう調べたらいいか分からず困っていたのですが、引数の取得で検索すればなんとかなりそうですね。
後は自分で調べてやってみます。ありがとうございました。
バッチだと for文を使います 複雑なことをするのであればVBで直接読み込む方法もあります
バッチでiniファイルなんて読み込めるの? VBとかからGetPrivateProfileStringとかのAPIを使うんじゃないの? まあ力技で出来ないことはないんだろうけど自分が知らないだけで一般的なやり方というのがあるのかな?
ググればふつうに出てくるようだが。(内容まではちゃんと見てない)
>>355 >>354 の言うようにfor文を使う
わかりやすいとは言えないし特殊文字が含まれると色々面倒なのでおすすめはしない
バッチファイルでファイル操作って一見ちゃんと動いてるように見えて穴だらけって場合が多いからやりたくないな wshで実装したりps辺りで既存のAPI呼び出す方がいい
batで設定呼び出したい時はiniじゃなくてsetting.batに変数を直接記述してcallしてるわ このやり方も良いやり方なのかどうか分からんけど
http://ascii.jp/elem/000/001/630/1630041/ Windows 10 RS4に追加された「curl」と「tar」コマンド
って curl と tar が追加されるんだ
PowerShell にも curl コマンド(エイリアス)があってややこしさが増すな
でも、標準で使えるようになるのはバッチファイル使ってる身とすれば
嬉しくはある
ファイル圧縮バッチを
hta の画面にドロップするだけで実行するやつ作った
http://2chb.net/r/csaloon/1518353191/843-846 ファイルをバッチファイルにドロップして引数受け取りは普通にあるけど
ファイル名の一部を文字列としてドロップしても起動されないのでこういう方法を取った。
>>360 Windows10 なら、WSL で、MS Store から、Ubuntu 16.04 LTS をダウンロードすれば、
curl, tar も入っている
他のLinux のコマンドも、一杯ある
普通に使える ubuntu run curl --help
Linux(Ubuntu)側のbash、Windows側のPowerShell・コマンドプロンプトから、 相互のアプリ・コマンドを実行できる 相互のパイプも、つなげられる つまり、Linux側のbashは、Windows10 の1つのアプリになっている
> Ubuntu 16.04 LTS をダウンロードすれば、 この手の前提条件が無いことがバッチのメリットなのに...
>>363 Web開発テスト用の範囲を超えてない。
当のMSが「運用には使ってくれるな」つってるのによ。
お前馬鹿か?馬鹿だろ。
>>368 WSLはウェブサービス開発で使って、
実際にそのウェブサービスを動かす(=運用)するのは
ネイティブなLinuxの上だぞ。例えばAzure上のLinuxとか
運用に使ってくれるなっていうのは、WSL上でウェブサービスを動かして
実際に不特定の人にサービスを提供するなっていう意味だ
WSL 上で、Webサーバーとかを常時接続させて運用できない まあ最初から、自分のデスクトップPC を外部につなげて、 そんなサービスをする奴は、居ないだろ
>>370 端末のスタートアップスクリプトに使うのも用途外。
だから「使える」とか言うのは明らかに言い過ぎ。
お前馬鹿か?馬鹿だろ。
>>373 > 端末のスタートアップスクリプトに使うのも用途外。
端末のスタートアップスクリプトの話なんかしてないんだが、
何を言い出してるんだ? そもそも端末のスタートアップスクリプトの
意味わからねぇw
>>372 運用っていうから悪いんだよ。
「一般ユーザーに対してのウェブサービスの提供」
MSが使うなって言ってるのはこれだけだよ
うん、ちゃんとFAQに書いてあったね
https://docs.microsoft.com/en-us/windows/wsl/faq > Also, even though you will be able to run many popular server applications (e.g. Redis),
> we do not recommend WSL for server scenarios ? Microsoft offers a
> variety of solutions for running production Ubuntu workloads in Azure, Hyper-V, and Docker.
サーバーアプリケーションを実行できるが、サーバーとしてのシナリオは推奨してないと
もう一つ、誰のためのものですか?という質問には > Who is this for? > This is primarily a tool for developers -- > especially web developers and those who work on or with open source projects. 第一に開発者、特にウェブ開発者やオープンソースプロジェクトを行ってる人 > This allows those who want/need to use Bash, common Linux tools (sed, awk, etc.) and > many Linux-first tools (Ruby, Python, etc.) to use their toolchain on Windows. bashや多くのLinuxツールや言語を使いたい人のためのものと
Windows のコマンドプロンプトから、 wsl bash -c "echo 'hello'" 出力結果 : hello これぐらいのLinux の起動・実行・終了は、1秒! 定時処理ぐらい楽勝 サーバーみたいに常時実行しなければ大丈夫
>>377 wsl.exeを使うなら bash -c はいらないぞ
wsl echo hello でよい
wsl echo --help と wsl /bin/echo --help の実行結果が違うから
wslの中ではbash上で動いているっぽい
wsl ps axfu やってもbashいないんだけどな
まあ詳しい人に聞けば、そこら辺の動きは知ってるだろう。
あと、別にLinuxは起動してるわけじゃないのでLinuxの起動と書かれると違和感がある。
WSLはLinuxカーネルを模したサブシステム
Windows のコマンドプロンプトで、 >where wsl C:\Windows\System32\wsl.exe >where ubuntu C:\Users\ユーザー名\AppData\Local\Microsoft\WindowsApps\ubuntu.exe wsl, ubuntu(Linux), bash の関係がよくわからない 漏れのノートPC は、i3、メモリ8GB、SSD だけど、 Windows10 の単なるアプリだから、起動・実行・終了で、1秒ほど WSLは、もう正規版だし、単なるアプリとして使う分には、問題ないだろ
書き忘れた Windows のコマンドプロンプトで、 >where bash C:\Windows\System32\bash.exe
Windows のコマンドプロンプトで、 >wsl echo hello >ubuntu -c "echo hello" >bash -c "echo hello" これらは皆、hello が出力されるけど、書き方が異なる wsl では、echo がサブコマンドになっているのかも
>>379 俺もちゃんと調べたわけじゃないけど、
開発の歴史からすると、
最初はbash on ubuntu on windowsという扱いで
bash.exeでUbuntu上のbashが起動できる(おまけでLinuxコマンドも使えるよ!)という扱いだった。
このbashが起動できるという仕組みを提供しているものの名前がWindows Subsystem for Linuxだったわけだが
開発が継続しLinuxカーネルとの互換性があがってもうbashだけが起動するもんじゃないよねってことで
Windows Subsystem for Linuxの略であるwslと呼ばれるようになり。
wsl.exeができた(おそらくbash -c "コマンド" と面倒な書き方をしなくて良いラッパー)
それと前後して、ubuntuだけじゃなくopenSUSEやFedoraも動くよ!(いやFedoraまだリリースされてないんだが)
ということになり、bash.exeやwsl.exeで起動するのはどっちのディストリよ?
ってことでそれを切り替えることができるwslconfig.exeができた。
また直接wslconfig.exeの設定によらず、ubuntuやopensuseを直接起動するための
ubuntu.exe やopensuse-42.exe が出来た。
こんな所だと思う
なんでバッチスレでパソコン博士がWSLでイキってるの?
>>381 ubuntu /?をするとわかるが、
ubuntu run echo helloが正しい
ubuntu.exeもwsl.exeもbash.exeもパラメータの扱いが違うだけで
ディストリ上のbashを実行していることは確かなようだ
>>383 Windows 10において、バッチファイルでWSLと連携するのは
当たり前の話になってきているから
ubuntuは Usage: <no args> - Launches the distro's default behavior. By default, this launches your default shell. と書いてあるから、bashじゃなくてデフォルトシェルが呼び出されるのかも。 うーん、どれを使うのが良い(汎用的)なのだろう?
wsl(Linux のbash)・PowerShell・コマンドプロンプトの3つが、 パイプでもつなげられるし、シームレスになってきて、CUI が統合されてきているから、 個別の話よりも、3つのCUI をパイプでどうつなげるかの方に、 話の焦点が移ってきている
bash は、C:\Windows\System32\bash.exe を起動する ubuntu は、bash, zsh など、自分がデフォルトに設定した、シェルを起動する。 環境変数、$SHELL >wsl echo $SHELL /bin/bash wsl コマンドが、ubuntu, open suse など、 自分がデフォルトに設定した、Linux を起動 >wslconfig /list Windows Subsystem for Linux ディストリビューション: Ubuntu (既定) 推測で書いたけど、普段は、wsl を使うと良いかも
>>383 オモチャ買ってもらった子供が「見て見てこれすごいんだよー」って言ってるような感じ
暖かく見守ってやれ
>>389 WSL出た頃なら仕方が無いが...
やっぱパソコン博士レベルだと今頃になってやっとおもちゃを見つける感じなのか。
へへーん、ぼくなんてまえからもってるもんねー それはすごいねー w
さすがにスレチだからもうやめとけと思うけど、WSLについて少し調べてみようと思うきっかけにはなったわ。
パソコン先生に恨みでもあるのかな? そんな話をしてもバッチファイルを書く上で 何の意味もないと思うんだが、話をしたいのだろうね
>>390 Bash on Ubuntu on Windowsは、早く使いたかったんで
Inside Previewに変えてまで使ったよ。
GUIアプリには対応していないって書いてあったが仕組み上
GUIアプリ動くんじゃね?ってそこの頃はまだ情報が少なかったけど
実際に自分で試してxeyes は動いたーって2ちゃんねるに書いた記憶がある
自分語りとか余計なことをダラダラ書き連ねるから嫌われるんだよ。
嫌うのは相手の問題だからどうしようもない 俺に対する勘違いは、俺の問題だから解決する必要がある
例えば「aaa」という名前のODBCの設定は以下のコマンド reg query HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\aaa を実行すると HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\aaa Driver REG_SZ C:\WINDOWS\system32\SQLSRV32.dll Server REG_SZ aaa Database REG_SZ aaaDB LastUser REG_SZ ***** Trusted_Connection REG_SZ Yes のように表示できますが この設定の接続先データベース(上記ではaaaDB)をコマンドで変更することは出来るのでしょうか?
reg add HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\aaa /v Server /t REG_SZ /d bbbDB とかでだめなん
>>400 「/v Server」は「/v Database」の間違いですよね?
これでバッチリいけました。ありがとうございます!
windows10 のコマンドプロンプトの、文字色を変えるエスケープシーケンスで、 prompt ^[[1;36m[$d$s$t$h$h$h] ^[[1;33m%USERNAME% ^[[37m$p$_$g$s prompt $e[1;36m[$d$s$t$h$h$h] $e[1;33m%COMPUTERNAME% $e[37m$p$_$g$s echo ^[[1;36mバッチファイル^[[37m は動作しますが echo $e[1;36mスクリプト$e[37m だと駄目でず。 ( ^[ は、CTRL+[ で入力する制御文字(\x1B)) echo で有効な「$e」の様な入力方法は有りますか?
バッチファイルで 空行を除く最終行にhogeって文字がなかったら追加して改行 -- hogeとかになってたら削除してhoge追記して改行 って事をやりたいんですけどどうやったらできるかおせーてください
Ruby で作った require 'stringio' ary = [] File.open(ARGV[0]) do |io| text = io.read text.rstrip! # 末尾の連続した空白を、すべて削除する sio = StringIO.new text ary = sio.readlines # 全行を配列に読み込む if ary[-1] == '-- hoge' ary[-1] = "hoge\n" elsif /hoge/ !~ ary[-1] # hoge を含まない ary[-1] += "hoge\n" else return end end # 一旦ファイルを削除してから、書き込む File.open(ARGV[0], 'w') { |io| io.write ary.join }
>>405 あのーバッチって聞いてるのにrubyのスクリプト出されても困るんですけど
やらなくても言い余計なことをして場を混乱させる人って必ずいるよね
ロジック真似すればいいだけじゃん 作ってくれじゃなくて教えてくれなんだから Lispで回答されて読めないのは理解できるが 上のRubyくらいなら何の問題もないだろ
聞かれてるのはバッチでの実現手段なのにロジックとか言い出してどうすんだよ
文字列の比較も削除も面倒だから バッチではやらないほうがいい
vbscript版作ったけどバッチ限定なら貼らなくいい?
>>404 一応無理矢理ここまで作ってみたけど、ファイルの中身や指定文字列に特殊文字が入ってると
容赦なくコケるという地獄仕様のままなんで、限定的にしか使えないと思う。
有意な最終行の内容にあわせて結果ファイルを出力するバッチ
https://pastebin.com/mh9BZDCv コケないようにやるにはどうすればいいのかな・・・。誰かうまいやり方があれば教えてくれ。
>>414 俺の選んだ手法がアホなだけかもしれんけど、バッチって基本的に制約多くて泣けてくるもんだから・・・( ノД`)
せっかくだしvscript版もどこかに貼ってもらえるとありがたいな。
>>412 >>1 にそれらしいことは書いてあるから、ダメってことはないだろう
ただ、「Jscript・Perl等の埋め込み」って何だろう
バッチファイルに他言語のコードを埋め込めるのか?
「バッチ JScript」とかでググればいいんじゃないか
>>413 ありがとうございますとても参考になりました
@echo off set n0=0 set n1=0 set n2=0 set file="xxx.txt" set newfile="new.txt" set word=xxx type nul>new.txt for /f "tokens=1* delims=:" %%i in ('findstr /n "." %file%') do set n0=%%i for /f "tokens=1* delims=:" %%i in ('findstr /n /c:"%word%" %file%') do set n1=%%i for /f "tokens=1* delims=:" %%i in ('findstr /n /c:"-- %word%" %file%') do set n2=%%i if %n0% equ %n1% if %n1% neq %n2% goto :eof if %n0% equ %n2% (call :del-line %n2%) else (copy /y %file% %newfile%>nul) call :add-line move /y %newfile% %file%>nul goto :eof :del-line for /f "tokens=1* delims=:" %%i in ('findstr /n ".*" %file%') do if %%i neq %1 echo;%%j>>%newfile% goto :eof :add-line echo;%word%>>%newfile% goto :eof
ループ回しすぎじゃね? 小さいファイルならいいだろうけど でかいログファイルとかだと辛いかも
バッチのfor /f ~ in (ファイル)って1行ずつシーケンシャルにメモリに読んでるって考えていいのかな?
>>420 wordってのがどれだけの頻度で出現するかで違ってくる
もし殆ど書かれてないのなら、最後が
--hogeならforループはほぼ2回分(wordが各行当たり前にあるのなら4回分)
hogeやなしならforループはほぼ1回分(wordが各行当たり前にあるのなら3回分)
wordと--wordの検索は一緒のループでできそうだけど
あと、データ中に、&|^%"'\や%date%を入れてみたけど問題ないみたいだ(win7)
いや各行にwordと--wordのどっちかしか無いとするなら--wordの場合で最大でも3回分か
set /a a0=0,b=0,c=1,e=1 for /f "delims=: tokens=1*" %%i in ('findstr /n .* in.txt') do ( set "a%%i=%%j" if defined a%%i set /a b=%%i set /a c=%%i+1 ) setlocal enabledelayedexpansion if not "!a%b%!"=="!a%b%:hoge=!" set /a c=b set "a%c%=hoge" del out.txt :y echo.!a%e%!>>out.txt set /a e+=1 & if !e! leq !c! goto y
1万行ある適当なテキストファイルでテストしてみた
>>419 の方、3.1秒 (最後に-- hoge行を加えた場合 7.5秒)
>>424 の方、2分14秒(最後に-- hoge行を加えた場合 2分14秒)
ってな結果になった
>>419 の方はforのループ回数は多いが、比較すると速いという結果になった
Oh...ワタシ findstr /n ノキョドウカンチガイシテタネ...
>>419 、
>>424 は対象ファイルの行頭にコロンがあると消されちゃうね。
そういう後から判明するバグが紛れ込むからバッチで文字列処理は嫌なんだよな
先頭から連続するデリミタは全て消される
>>419 ,
>>424 どっちもダメ
>>424 は /? もダメ
abc
:::def
/?
-- hoge
俺が仮組みしてみたやつもforの変な仕様で空行削除されてた バッチだけで手軽には無理だな 素直に適当なスクリプト使った方がいい
>>430 セミコロンをピリオドとかコロンとにするといいみたい
echo; → echo:
>>425 424のほうのgoto labelをfor(/L)にすると多少速くなるけど
findstrを繰り返し使ったほうが速いね
メモリにも優しい
>>432 どの文字に変えてもその文字が来ればデミリタ判断されておかしなぶった切りが起こるから
デミリタ文字のエスケープ処理が必要になるんでは
set /a a=0,b=0,c=0,d=1 & del out.txt 2> nul for /f "delims=:" %%i in ('findstr /n . in.txt') do set /a a=%%i for /f "delims=:" %%i in ('findstr /n hoge in.txt') do set /a b=%%i if %a%==%b% set /a c=b for /f "delims=0123456789 tokens=*" %%i in ('findstr /n .* in.txt') do ( set "e=%%i" setlocal enabledelayedexpansion if !d!==!c! goto x echo.!e:~1!>>out.txt endlocal set /a d+=1 ) :x echo hoge>>out.txt
>>437 元ファイルにechoで追加ですむ場合もあるが
ファイル終端が改行になってるか確認する方法が思いつかない
>>438 終端に改行があろうがなかろうが、echoで出力すれば改行は付加されるよ
あとは参考になるかわからんが
set LF=^
setlocal EnableDelayedExpansion
findstr /n .* in.txt
findstr /n $ in.txt
findstr /n !LF! in.txt
の出力の差で終端改行のありなしの見分けがつくかも
(setとsetlocal行の間の空行は省略しないこと)
改行コードが、CR/LF、LF、CRで違った結果が出るところが面白いよ
>>439 ファイル終端が改行になっていないと最後の行の後ろにhogeがくっつくだけだよ
>>419 で試してみなよ
echoで空行を追加してからhogeを付ければいいんだけど
それだとファイル終端が改行になっていたら余計な空行ができる
コマンドプロンプトの画面で以下の<コマンド①>を入力すると現在の年月日時分秒が表示されるのですが これを変数に入れるにはどうすれば良いのでしょうか? 以下の<コマンド②>ではうまく入りませんでした・・・ <コマンド①> powershell -command "date -f yyyyMMddHHmmss" <コマンド②> set NICHIJI=powershell -command "date -f yyyyMMddHHmmss"
>>441 for /f "delims=" %%G in (‘powershell -command “date …”’) do set “NICHIJI=%%G"
>>441 外部プログラムの標準出力を取り込むのが目的ではなくて、単に現在日時をセットするだけならバッチのみで済むけど
set NICHIJI=%date:/=%%time::=%
set NICHIJI=%NICHIJI:~0,-3%
>>442 すみません、分かりにくい文でした
>>437 を改造しようとしたが改行がネックだと言う話
以下の通り改造してみた
>>437 の4行目と5行目の間に一行挿入
if %c%==0 goto y
ラベル:x以降は変更
:x
echo hoge>>out.txt
goto :eof
:y
copy in.txt out.txt & call :x
for /f %%i in ('findstr .* out.txt') do set "e=%%i"
if "%e%"=="hoge" goto :eof
copy in.txt out.txt
echo.>>out.txt
goto x
echo と同じ行で何か実行すると空白が入る echo.>a echo.>b & rem dir a b
豆知識その2 echo と同じ行でパイプ実行すると表示が変わることがある set a=%%b%% set b=xxx echo %a% echo %a% | more
豆知識その3 文字化け嫌なら遅延展開で @echo off set "a=a > nul" set "b=b & rem" echo %a% echo %b% echo ------ setlocal enabledelayedexpansion echo !a! echo !b! pause
プログラムからファイルの追加・削除・変更などを行っている最中のフォルダに対して「dir /s」のコマンドを実行した場合 そのせいでプログラムからの処理を邪魔してしまうことってあるのでしょうか?
絶対に邪魔をしないと言い切るのは難しいな。悪魔の証明
普通は影響しないと思ってていいだろう そのプログラムがシビアな待ち時間を気にするような造りにさえなってなければね
ちょっとハマってしまったのでアドバイスをいただきたく。 @echo off cd /d %~dp0 setlocal ENABLEDELAYEDEXPANSION FOR /f "delims=" %%i IN ('cmd /u /c ECHO;名') DO ( SET CR=%%i SET CR=!CR:~0,1! ) SET LF=^ set CRLF=!CR!!LF! set DATA=alpha beta gamma set DATA2=%DATA: =!CRLF!% @echo ---------------------------------------------- @echo !DATA2! @echo ---------------------------------------------- (@echo !DATA2!) > testdata2.txt @echo -------------FOR開始--------------- FOR /F "tokens=*" %%a in ('echo !DATA2! ^| findstr /C:"be"') DO ( @echo FORに入った @echo %%a ) @echo -------------FOR終了--------------- :last pause
>>454 でやりたいこと ・空白区切りの文字列群が入っている環境変数DATAがある。 ・ここから、特定の文字列(ここでは"be")を含む文字列だけを取り出したい。 ・空白を改行(CRLF)に置換してfindstrすればいいかと思ったが、 @echo !DATA2! > testdata2.txt では確かに改行されたファイルができるものの、 @echo !DATA2! | findstr /C:"be" だと、そもそも @echo !DATA2! が "alphaCRLFbetaCRLFgamma"のような単一行扱いでfindstrに渡されるらしく(?)、うまくいかない。 出力結果は -------------FOR開始--------------- FORに入った alpha -------------FOR終了--------------- となってしまう。 (echo alphaCRLFbetaCRLFgamma をやろうとして、CRLFのとこまでしか出力してないということ?) ・type testdata2.txt | findstr /C:"be" にすればいいのだが、できれば一時ファイルへの出力は行いたくない。 何か良い方法はないでしょうか。 空白区切りならcallとshiftで回せばいいのでは @echo off set DATA=alpha beta gamma call :SEARCH %DATA% goto :eof :SEARCH if "%1" == "" goto :eof echo %1 | findstr be shift goto SEARCH
とあるプロンプトを表示して確認画面でyes/no入れてyesが表示されたら処理を続けるnoが入れられたらgoto ENDって事がワンライナー(一行)でやりたいんですけど良い方法ありませんか?
>>458 は例えば↓なのを一行でやりたいんです
setlocal
set /p answer="実行しますか(y/n)? : %answer%"
if "%answer%"=="y" (
echo "start"
) else if "%answer%"=="n" (
echo "cancel"
exit /b 1
)else (
echo "other key"
exit /b 1
)
endlocal
ワンライナー云々抜きに choice.exe は使ったらダメ?
database.txt にある複数の文字列を delete.txt の内容で消去したいと考えているのですが 「複数の文字列 削除」でぐぐっても複数ファイルから単一の文字列を削除するtipsしかヒットせず迷子の状態になってしまいました。 調べ方を教えていただけないでしょうか、よろしくお願いします。 [database.txt] りんご,ごりら,らっぱ,ぱんだ,だちょう,うし,しお,おにぎり,りす, [delete.txt] ごりら ぱんだ うし りす [output.txt] りんご,らっぱ,だちょう,しお,おにぎり,
>>461 XP なら追加が必要だが、Microsoftさまのリソースキットにはある
2003 もしくは XP 64bit 以降なら
>>462 のいうように標準で存在する
まさか XP?
>>464 確かWindowsXPだけでなくWindowsNT4.0やWindows2000の場合も
別途リソースキットからchoice.exeを持ってくる必要があったな。
>>463 Ruby で作った
# 行区切りのキーワードファイル
text_kw = File.read 'keyword.txt'
keywords = { }
text_kw.each_line do |line| # 1行ずつ処理する
line.chomp! # 末尾の改行を削除する
# 0文字でなければ、ハッシュに追加する
keywords[line] = true unless line.length == 0
end
text = File.read 'data.txt'
# 末尾の改行を削除して、カンマ区切りで配列に入れる
words = text.chomp!.split(',')
# その単語がハッシュにあれば、配列から削除する
words.delete_if { |word| keywords.has_key? word }
# カンマで連結して、ファイルに上書きする
File.write('out.txt', words.join(','))
このrubyガイジはバッチスレにも住みついてんのか
↓ガイジのおともだち 667 名前:ピラフ ◆9Jro6YFwm650 [sage] 投稿日:2018/04/05(木) 22:04:35.89 ID:SYfKFmGc >>666 * * * + グッジョブ! n ∧_∧ n + (ヨ(* ´∀`)E) Y Y * >>456 いただきたく。
ください。
なんでわざわざ長ったらしい書き方するんだろうね。
しかも質問してるくせに偉そうという。
>>462 何故かWindowsPEに入っていない不思議
>>470 回答者でもないお前が質問者の態度を問うな
>>473 おれは日本人としての道徳を説いてるんだが
>>474 あそこは日本人じゃなく山猿が結構いるよ
for /l %%n in (1,1,10) do (
質問させてください。 プログラムの標準出力を変数に代入する方法を調べ、以下のような方法を見つけて動作を確認しました。 FOR /f "DELIMS=" %%A IN ('ECHO ABC') DO SET ABC=%%A しかし、'ECHO ABC' の部分にダブルコーテーションが含まれているとうまく動作しませんでした。 何らかの方法でダブルコーテーションをエスケープする必要があると思うのですが、 その方法をご存知の方がいらっしゃれば教えていただけないでしょうか。 よろしくお願いします。
@echo off FOR /f "delims=" %%A IN ('ECHO hoge^"hoge') DO SET "ABC=%%A" echo %ABC% pause
こんなファイルがありまして 2018/04/21 09:30:00 count 10 2018/04/21 10:00:00 count 20 ↓のように変換出力したいです 2018/04/21 09:30:00<tab>10 2018/04/21 10:00:00<tab>20 どのようにしたらいいでしょうか
>>480 <tab>はTABコードだと判断したが、もし単なる文字列ならその部分は修正してくれ
@echo off
setlocal EnableDelayedExpansion
type nul>out.txt
for /f "delims=N" %%I in ('cmd /u /c echo 三') do set TAB=%%I
set n=0
for /f "tokens=* delims=" %%i in (in.txt) do (
set d!n!=%%i
set /a n+=1
if !n! geq 3 set n=0&echo.!d0!%TAB%!d2!>>out.txt
)
endlocal
下手にバッチでやるよりエディタ等で \ncount\nをtabに一発置換するだけのような
>>481 これでできました
でも難しくて意味が分からないけど
>>482 秀丸でやったらできました
これは楽ですね
お二人ともありがとうございます
>>483 今まで何度か出てたはずだけど覚えてないかな?
漢字の三は、SJISでは8E4Fだが、Unicodeでは、U+4E09
英字Nは、ASCII(SJIS)で、4E
HT(水平タブ)文字は、ASCII(SJIS)で、09
>>481 は3行1セットを大前提として1行目+タブ+3行目で1行として出力するバッチやね
中身が何かっての全く確認しないから変な行あったら以後盛大に誤爆する
@echo off type nul>out.txt setlocal enabledelayedexpansion set n=0 for /f "delims=" %%i in (in.txt) do ( set "d!n!=%%i" & set /a "n=(n+1)%%3" if !n! equ 2 if not "%%i"=="count" echo.!d0!>>out.txt&set n=1& set "d0=%%i" if !n! equ 0 echo.!d0! !d2!>>out.txt ) !d0!と!d2!の間は普通にtab入力
バッチは不特定多数に提供するんでなければ、やっつけでいいんだよ 取り合えず用が足せればいい ああいう場合にどうだとか余計なことはそういう場面に遭遇してから対処すればいい まあ違う考えを持ってる人もいるだろうから俺の考えではと限定しての意見だが
元となったデータを見てると、何かのプログラムで出力した結果のようだから イレギュラーなデータはそもそもあり得ないのかもしれない それをイレギュラーなデータがあったらと考えていろいろ対処するのどんなもんなのかな
あと、
>>486 は、こういう処理をしているんだからそれを念頭においてねってことだけで、
何もその点を修正しろとか言ってないわけよ
>>486 も、何をしてるのか分かっていて使う分にはそれで良いと思ってるんじゃないのかな
>>484 が
> でも難しくて意味が分からないけど
こんな事言ってるから何してるのか書いただけよ
それ以外の意味は無い
バッチファイルを直接ダブルクリックした時は処理の最後にpauseをかける(=コマンドプロンプトウインドウを 閉じずにホールドする)条件にして、コマンドプロンプトから呼び出された場合はpauseはかけずに処理を 終了するという実装をしたいんですが、いい方法ありますか?
>>494 引数で処理を分けるか、pause有無でバッチファイルそのものを分ける。
%0 参照して分岐すれば? echo %0 pause
レスありがとうございます>各位
すいませんダブルクリックと書いたのでミスリードになってしまったのですが、実際にはD&Dで引数も使用します。
なので
>>496 の環境変数参照して/Cオプション実行しているかどうかで分岐しようと思います。
64桁の10進数を16進数に変換する方法、探したけど見つからなくて バッチファイルだけでやるのは無理があるでしょうか。 javascriptでなら巨大な桁数いけるサイトはあったのですが バッチファイル内で大量に処理したいのです。
ネットワークカードに複数IPアドレスをバッチファイルで当てる方法教えてください。 netsh interface ipv4 set add name="ローカル エリア接続" static addr1="192.168.15.35" このあと 192.168.1.35も割り当てたい、よろしくお願いいたします。
自己解決 netsh interface ip add address name="ローカル エリア接続" addr=192.168.1.35 mask=255.255.255.0
>>501 普通の手段だと無理だと思う。
1. 整数演算はOSのbit数の上限までしかできない
2. 文字列として変換するにしても255⇒0xFFが限界
…。
3. そもそも符号無し16進??有りの16進??
>>501 ほぼ無理
自転車で崖を上がりたいというようなもの
あきらめて、これを機に何かの言語を覚えるといろいろな場面で一生使える
一番簡単なのはinstall不要なgawk
訂正。64bit環境でも調べたけど、最大2147483647(符号付32bitのMAX)だった。
>>504-507 ありがとうございます。hex2decは試行済でした。
1234567890000987654321000000
を渡すと
7766001854005038656 = 0x6BC6618A48FECE40
このように崩れます。
やはり無理がありますか。。。
gawkはlinuxのようですね。windowsで実現する方法を求めていました。
バッチファイルでは出来そうにないのでWSH JScriptあたりを探してみたりしていました。
他手段を探してみたいと思います。ありがとうございました。
batでも出来るんだけど、実用な時間で出来るかと言われると何ともねえ
@echo off
setlocal
set hex=0123456789ABCDEF
set in=1234567890
set out=
set bin=
:loop
call :div2 in s
set bin=%s%%bin%
if defined in goto :loop
:loop2
set h=000%bin:~-4%
set /a h=("%h:~-4,1%<<3")+("%h:~-3,1%<<2")+("%h:~-2,1%<<1")+%h:~-1%
set bin=%bin:~0,-4%
call set out=%%hex:~%h%,1%%%out%
if defined bin goto :loop2
echo.0x%out%
endlocal
goto :eof
:div2
set dst=
set s=0
:divloop
set d=%in:~0,1%
set in=%in:~1%
set /a s=s*10+d
set /a h="s
>>1 "
set /a s%%=2
if defined dst (set dst=%dst%%h%) else if %h% gtr 0 set dst=%dst%%h%
if not defined in set in=%dst%&goto :eof
goto :divloop
これはやっつけで作ったんで、もっとスマートにできるかも知れない なお、div2ルーチンは最初変数を独立させるためにsetlocalで別環境にしてた名残が呼び出し元の引数に残ってる(無意味だから何で付けてるのって思わないように)
>>510 いや実際やってみればわかる
64桁程度なら一応待てる??時間内で終わるよ?
inに10進数値をセットするが、%1に書き替えて起動時の引数で与えるようにすれば色々試せるだろう
>>509 元の質問者じゃないけど、これ動かすとたまに「プロセスはファイルにアクセスできません。別のプロセスが使用中です。」って出る。
自分で書いたbatもループとかcallが多いとこれが出たりリダイレクトに失敗してたりする事があるんだけど何が原因?
ごくごく稀に飛ぶはずのないラベルに飛んで動作不良起こしたりもする。
>>514 OSは何だろう?
こっちは、win7pro 64bit
通常そういう変な動作はワークエリアが残ってない場合なんかに起きる
環境変数をいっぱい定義して領域が残ってないとか
そういう場合、コマンドプロンプトを一旦閉じて再度起動して初期状態にして試してみる
win2000で環境変数領域は2048バイト、winXPでは8192バイト、それ以外はヘルプにコマンドプロンプト関連のの説明が無い
でもまあ大抵はbatに問題がある
>>509 のはこっちでは70桁を指定しても正常に動作してるが、
setlocalで子環境を作ってて、サブルーチンから抜けるときにはendlocal無しにgoto :eofしてるので
その辺が問題なのかもしれない
この辺はよく分からないので、一度setlocal,endlocalを削除して試してくれ
>>514 そのメッセージがbat実行直後なら(つまりあまりに瞬時で実行してるように思えない場合)、
本当にbatファイルが別プロセスで使用中なのかも知れない
裏で何かのプログラムがbatファイルを握って離さないとか
(インデックスサーチとかセキュリティチェックとかは、俺は作動させてないのでどうなのかは知らない)
>>516-517 OSはwin10 64bitです。
セキュリティソフトはWindows Defender、インデックスサーチはWindows Search、Everythingを使ってます。
これらは利用者多いのに同様の不具合は聞いたこと無いから関係無いかも?
環境変数はいくつか自分で追加したけど問題になるほど登録してるとも思えないしよく分からない。
他になにか悪さをしているソフトがあるのかなあ。
>>501 もう見てないかも知れないが、
俺の古いPCで、64桁で0.4秒ほどの実行時間です
@echo off
setlocal enabledelayedexpansion
set "a=1234567890123456789012345678901234567890123456789012345678901234"
set "g=0123456789ABCDEF"
set "h="
set /a b=8,e=100000000
for /L %%i in (8,8,56) do if not "!a:~%%i,1!"=="" set /a b=%%i+8
set "a=0000000%a%"
set "a=!a:~-%b%!"
for /L %%i in (%b%,-8,8) do set /a "a%%i=1!a:~-%%i,8!-e"
:x
set /a c=0,f=0
for /L %%i in (%b%,-8,8) do set /a "d=a%%i+c*e,a%%i=d
>>4 ,f|=a%%i,c=d&15"
set "h=!g:~%c%,1!%h%"
if %f% neq 0 goto x
for /f "delims=0 tokens=*" %%i in ("%h%") do set h=%%i
echo %h%
pause
>>515 の gcalcを使用すると簡単
>type a
printf("%x\n", 1234567890123456789012345678901234567890123456789012345678901234)
>gcalc < a > b
>type b
0x30046030f26f462d7ac21a27eb9d53fff233c7acd12d87e96aff2
>>509 >>519 すごい!ありがとうございます!
なんか微妙だなーと思って戻ってみたら凄いスマートなのリプきてた。
gcalcとも比較してみましたがかなり早いですね。㍉秒二桁くらい違う。
使わせていただきます。ありがとうございました!
>>501 Ruby では、
num = 9999_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890
num.to_s(16)
#=> "184e78450dd8c1fca3b502d65e4f6fb73c42c47ccff196ce3f0ad2"
>>520 gcalc面白いね
こんな書き方が通っちゃうんだー
--bat--
@echo off
gcalc -d config(\"tab\",0), base(16), <in.txt; quit;
rem gcalc -d config(\"tab\",0), base2(16), <in.txt; quit;
--in.txt---
1111111111
2222222222
3333333333
%1や環境変数が数字だけか判定するのが面倒 ぐぐってやりかたはわかったが、もっとすっきりくっきりな方法はないですか 正規表現だと ^\d+$ でおわりなのに set W=x%1 set W=%W:0=% set W=%W:1=% set W=%W:2=% set W=%W:3=% set W=%W:4=% set W=%W:5=% set W=%W:6=% set W=%W:7=% set W=%W:8=% set W=%W:9=% if '%W%=='x echo 数字
set X=100 echo %X%|findstr /X "[0-9][0-9]*"&&echo 数字 こうとか
@rem 2147483648 以上の数は扱えないため、大きい値が入る条件には不向き。 set "W=%1" set DUMMY=a set /A "DUMMY=W*1" if not "%W%"=="%DUMMY%" (echo 数字以外) else echo 数字のみ
ありがとうございます
>>527 findstって正規表現のようなことができるのですね、知らなかったです
>>528 英字だけ、数字だけだといいのですが、英数字混在文字列でエラーになりました
*1 の代わりに +0も同じでした
@echo off call :check_num %1 result echo %result% pause goto :eof :check_num if "%~1"=="" set "b=FALSE" & goto :eof for /f "delims=-+0123456789 tokens=* eol=" %%i in ("%~1") do ( set "a=%%i" if defined a (set "b=FALSE") else set "b=TRUE" ) endlocal & set "%2=%b%"
>>532 7行目の :check_num の次の行に
setlocal
を追加願います
なんか間違ってたので書き直した @echo off call :check_num %1 result echo %result% pause goto :eof :check_num setlocal if "%~1"=="" set "b=FALSE" & goto x for /f "delims=-+0123456789 tokens=* eol=" %%i in ("%~1") do ( set "a=%%i" if defined a (set "b=FALSE") else set "b=TRUE" ) :x endlocal & set "%2=%b%"
1"2 result"=="" set "b=FALSE" & goto x の使い方が誤っています。
"1" TRUE 1"2" ECHO は <OFF> です。
引数の中の " の対策すると大変なんで、やりたくない やりたい人、どうぞ
引数の中に cmd で特別な意味を持つ文字が有る場合は左に ^ を付けるか 全体を " で囲むしかないよ
call :check_num "%~1" result にでもすりゃいいのかな こういうのは考え出すときりが無い様な気がするが
分かってるのかどうか知らないが、 1"2"が、ECHO は <OFF> です。になるのは、eol="が効いてるため
eof= を消すと副作用があるし どっちにしろ引数に ; があると誤動作するみたいだし こりゃあもうお手上げだな
質問者が「もっとすっきりくっきりな方法」と言ってるんだから複雑でトリッキーな方法は求められてなないだろう
>>547 いつもそうなるけど、バッチじゃ諦めろ、が正解になってしまうよw
どんな方法でも良いから 引数の中に " とか ; が入ってても 正しく動作するのを頼む というのは絶対に無理なのかね
>>550 が不可ならそれを前提条件にするしかないだろ
ちょっと直してみた
@echo off
call :check_num "%~1" result
echo %result% & pause & goto :eof
:check_num
setlocal
set "b=FALSE" & if "%~1"=="" goto x
for /f "delims=-+0123456789 tokens=*" %%i in ("%~1") do (
set "a=%%i" & if not defined a set "b=TRUE"
)
:x
endlocal & set "%2=%b%"
とりあえず引数の " と ; の対策らしきもの 引数は行末まで1個のみ もう嫌気がさしたのでこれ以上はやめとく @echo off set a=%*" set /a b=0,c=0 setlocal enabledelayedexpansion :x set d="!a:~%b%,1!!a:~%b%,1!" if !d!=="" goto y if !d!=="""" set /a c+=1 if !d!==";;" set /a c+=1 set /a b+=1 & goto x :y endlocal & set c=%c% set "e=FALSE" & if %c% gtr 1 (goto z) else set "a=%*" for /f "delims=-+0123456789 tokens=*" %%i in ("%a%") do ( set "a=%%i" & if not defined a set "e=TRUE" ) :z echo %e%
>>550 @echo off
set "arg1=%1"
call :check_num arg1 result
echo %result% & pause & goto :eof
:check_num
setlocal EnableDelayedExpansion
set "b=FALSE"
for /f "delims=0123456789 tokens=*" %%i in ("!%1!") do (
set "a=%%i" & if not defined a set "b=TRUE"
)
:x
endlocal & set "%2=%b%"
goto :eof
引数に ; は指定できない(半角空白、カンマ、セミコロン、=は引数の区切りを示すため)
なお、遅延環境変数の展開を使わないでも以下のようなチェックで最初に弾けば可能
if "%arg1:"=%" equ "%arg1:"=”%" (echo ^"なし) else echo ^"あり
>554.bat 1"&ab" 'ab""' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 TRUE
>>555 これ以上はファイル渡しにすべきだろう
set /p
or
for /f delimes^=^ tokens^=*^ eol^=
>>555 554.bat とあるが実際は
>>553 のバッチ処理結果です
バッチ2行目の set コマンドの、左側の " が悪さをしてる
当然、下にあるチェック文もそのままでは使えない
引数 1;2 は実際には2つに分かれるが
これで TRUE を返すのは違和感あるので
>>552 では FALSE を返している
2つの %* を %1 にすれば TRUE を返せる筈
for /f %%i in ('"cmd /k prompt $h <nul"') do set BS=%%i set /p AAA=".%BS% 必要ですか?(y/n):"
僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方 役に立つかもしれません グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』 1FF18
バッチファイルと同じ階層に複数のテキストファイルがあって、 バッチファイルに次々とドラッグ&ドロップしたファイル名(拡張子含む)のみリスト化していくのは下記でできるのは分かったのですが… @echo off for %%f in (%*) do ( echo %%~nxf ) >> list.txt しかし、バッチファイルと同じ階層(別の階層でも良いですが)に複数フォルダがあり、各フォルダ内にテキストファイルが複数ある場合に、 フォルダをバッチファイルに1つ1つD&Dすることにより、そのフォルダ内のファイル名(拡張子)のみリスト化していくコマンドが分からず詰まっています。 /rを使わずにわざわざ1つずつD&Dするのは、単にファイル名の順番ではなく、リスト化を意図した順番にしたいからです。 どなたかお願いします。
@echo off cd /d "%~1" for /r %%f in (*.txt) do ( echo %%~nxf ) >> "%~dp0list.txt"
まずは、 >リスト化を意図した順番 これを詳しく説明するところからだな
>>564 できました
ありがとうございます!
>>565 意図した順番というのは、D&Dした順番、という意味でした
ファイル名に半角スペースを含んで拡張子も一つじゃない複数のファイルをドロップしてファイルごとに処理したいんだけどどうfor書いたらいい? 今はこんな感じで書いてるんだけど半角スペースで切れちゃう for %%f in (%*) do ( echo "%%~nxf" )
>>569 それで問題なさそうなんだけど、
どういう問題なのか分からないから詳しく現象を説明してくれ
>>570 ごめん半角じゃなくて全角スペースで切れてるみたいだ
"aaa bbb.txt"
こうなるはずがファイル一つドロップするだけで↓になる
"aaa"
"bbb.txt"
>>569 forじゃないけど、こんなんじゃあかんの?
:loop
echo %~nx1
shift
if not "%~1"=="" goto :loop
aaa bbb.txtとかa&b.txtみたいなのは%1等で受け取っても切れるね cmdの独特なコマンドラインパース処理が悪いともいえるし 半角スペース含まれてないのをいいことにD&D時にダブルクォートで囲わないOS側が悪いともいえるし困ったもんだな D&Dで処理するのはスクリプト言語使った方がいいかもしれん
いまだにスペース問題抱えてるとは思わないよな もう10数年以上前からあるのに
>571
こうで良くないかなぁ?/d を使うパターン。
for /d %%f in (%*) do (
echo %%~nxf
)
>>575 そういう仕様に依存している過去のコードの動作に影響が出るのさ。
そういうコードは今までずっと企業内で使われている。
作者不詳のまま…
ごめん、/d でも全角はアウトですた。 わけわからーん
昔、どこかのサイトで似たようなの見たけど %* を加工して解決しようとしてたが 数十行もあったようなw でも、俺が動作確認したら全然ダメだったし
>>571 Windows 10 Home 1803 だけど全角空白も & も
>>569 で問題なく処理できるよ
>>579 引数はフルパスだからな
フォルダ名に半角スペースあるだろ
>>569 for の代わりに forfiles を使うと ""付きファイル名なのでうまくいく(たぶん)
>>569 全角スペースを文字として扱うか、半角スペースと同じように扱うかについて、
cmdは中途半端な扱いをしているようだしな。
フルパスに半角スペースがあると、全角スペースは文字として扱われるが、
フルパスに半角スペースがないと、全角スペースは半角スペースと同じ扱いになる。
しかもクォートしただけでは対処できないという困ったことに。
対処方法としては、フルパスの何処かに半角スペースを入れてクォートするだけ。
>>579 Win10 Pro 1803 64bit。
全角がアウト。
>>580 ,
>>583 ああなるほど
すまん、ボケてたわ
全角空白の場合、ダブルクォーテーションで括られないのに、引数の区切り記号として取り扱われるってことか 間に、ダブルクォーテーションで括る操作をかませばいいか @if (0)==(0) echo off set arg=%* for /f "delims=" %%f in ('cscript //nologo /e:jscript "%~f0" %%arg%%') do echo %%f pause goto :eof @end for(var i=0,arg=WScript.arguments;i<arg.length;i++) WScript.Echo('"'+arg(i)+'"');
いや引数を各行に分解したから、括る必要もないな 最終行訂正 for(var i=0,arg=WScript.arguments;i<arg.length;i++) WScript.Echo(arg(i));
やっぱり括ってたほうがトラブルが少ないかも あと、半角空白が無いと括られないから、 a^b.txt とかはBATに入ってくる時点でもうダメだな %CMDCMDLINE% とか見てやれば可能だけど
結論としては、色々苦労して対応するより、 必ず半角空白をいれたフォルダにファイルを置くようにしたほうがいいね
これらは""で括れば問題ない a=b.txt a;b.txt a^b.txt
これは""で括ってもechoで化ける %cd%.txt
俺はバッチスクリプトを生成するスクリプトをPerlだのPhysonで書くときは ダブルクォートで囲わずに全部キャレットでエスケープしてる。 今回の件は %* が勝手に全角空白で区切る仕様が駄目なんだけど… スクリプトから呼ぶ場合には何とかなっても、D&Dの時点で引数を加工できないってとこに問題がある。 shift しても無駄、っていうところ…。 解決策…、ある??俺は思いつかない…。
a&b.txtとかはcmd. exeに入る前に対処しないとね BAT以外の別スクリプトにD&Dして、そっちで引数を加工後にBATを呼んでもらうようにするぐらい
ところでcmdスレなのに、なんでcmd. exeがNGワードなんだよ
確認してないけどcloudflareがコマンドインジェクション対策で弾いてんるんじゃないの ls -lとかもできなかったはずだし
Ruby, PowerShell を使った方が良い バグるのは低品質だし、時間の無駄
>>597 Ruby は実行環境のインスコがいる。
PoerShell はD&Dできない。
それ以前に、特殊な世界ではいまだに XP が現役だったりする。
Win7SP1以降のアップデートパッチを1個でも当てたら動作保証しませんなどというフザけた業務システムも実在する。
レジストリを汚すインスコは駄目だけど、ネイティブコンパイルしたコマンドをコピーして使う分にはおk、てな環境もある。
とりあえず、スクリプトを使用した D&D のファイルパス問題回避の最大公約数的解決は VBScript しかないんじゃないかな。
(さすがに Win9X な環境はもうないだろう…と思うけど)
使える環境なら検討した方がいいけど、安易な「○○使えばいい」という回答は頭が悪すぎる。
なら環境毎に勝手に使えばいいんだから最大公約数なんて決める必要ないのでは
>>569 無理矢理にバッチで書いてみた
@echo off
set "a=%cmdcmdline:"=""%"
setlocal enabledelayedexpansion
set /a b=0,n=0
set "s=" & set "d=""
:x1
if not "!a:~%b%,1!"=="/" set /a b+=1 & goto x1
:x2
if "!a:~%b%,1!"=="!d!" set /a n+=1
if !n! equ 6 set /a b+=2 & goto x3
set /a b+=1 & goto x2
:x3
set "a=!a:~%b%,-2! " & set /a b=0
:x4
if not defined a goto x8
if "!a:~%b%,1!"=="!d!" set /a n=0 & goto x6
下に続く
:x5 if not "!a:~%b%,1!"==" " set /a b+=1 & goto x5 set "s=!s!!d!!d!!a:~0,%b%!!d!!d! " & set /a b+=1 set "a=!a:~%b%!" & set /a b=0 & goto x4 :x6 if "!a:~%b%,1!"=="!d!" set /a n+=1 if !n! equ 4 set /a b+=1 & goto x7 set /a b+=1 & goto x6 :x7 set "s=!s!!a:~0,%b%! " & set /a b+=1 set "a=!a:~%b%!" & set /a b=0 & goto x4 :x8 set "s=!s:""="!" endlocal & set s=%s% for %%f in (%s%) do echo "%%~nxf" pause
>>602 ファイル名に全角スペースが含まれていない場合に""が一つ余計に出力されます
訂正 全角スペースが含まれず半角スペースが含まれている場合
レスありがとう でもこちらでは再現できない 出来たら具体例を
もしかしたらset文の行末にスペースがありませんかね? 行末のスペースが有ったら全て削除してみて下さい
>>606 もうちょい検証してこんなファイル名で発生するのを確認しました
"aーa b.txt"
""
専ブラからコピーしたんでスペースとかはありませんでした
長めのスクリプト貼るときはpastebinとか使ったほうがいいかもしれません
バッチファイル自体はtest6.batなのでスペースはありません このファイル名だと処理自体が終わらなくなりました ーa ーb ーc.txt
最初に検証したファイル名は aーa b.txt です
バッチファイル名 "test.bat" がOK, "test - コピー.bat" が NG "ー" がダメ文字っぽい なんだこりゃ
>>612 とりあえず最初の3行を
@echo off
setlocal enabledelayedexpansion
set "a=!cmdcmdline:"=""!"
set "a=!a:ー=/1!"
最後の5行を
:x8
set "s=!s:/1=ー!"
set "s=!s:""="!"
endlocal & set s=%s%
for %%f in (%s%) do echo "%%~nxf"
pause
ダメ文字の詳細は不明
まだ有ったら、/2 /3 ... 置換
これも追加 5行目 set "a=!a:―=/2!" :x8の次の行に set "s=!s:/2=―!"
漢字コードが関係しているのかも shift-jis chcp 932 utf-8 chcp 65001 で試してみたら
if文のバグ? @echo off setlocal enabledelayedexpansion set a=ーー set b=―― set c=xx set d="" if "!a!"=="!d!" echo NG1 if "!b!"=="!d!" echo NG2 if "!c!"=="!d!" echo NG3 pause 結果は NG1 NG2
>>617 if "!a!"=="!b!" echo NG4
結果は
NG4
まあ、見た目は似ているが...
ちなみに
>>617 をメモ帳にコピペして
変数 a の文字列で検索したら、なぜか変数 b にも一致したりする
逆もまた然り
>>612 if文の不具合は引用符絡みのようなので
それを削除して書き直しました
@echo off
call :set_arg arg
if not defined arg goto :eof
for %%f in (%arg%) do echo "%%~nxf"
pause & goto :eof
:set_arg
setlocal enabledelayedexpansion
set a=!cmdcmdline!
set /a b=0,n=0
set "s=" & set "c=/" & set "e= " & set "d=""
:x1
if not !a:~%b%^,1!==!c! set /a b+=1 & goto x1
:x2
if !a:~%b%^,1!==!d! set /a n+=1
if !n! equ 3 set /a b+=2 & goto x3
set /a b+=1 & goto x2
下に続く
:x3 set a=!a:~%b%,-1!& set /a b=0 :x4 if not defined a goto x8 if !a:~%b%^,1!==!d! set /a n=0 & goto x6 :x5 if not !a:~%b%^,1!==!e! set /a b+=1 & goto x5 set s=!s!!d!!a:~0,%b%!!d!!e!& set /a b+=1 set a=!a:~%b%!& set /a b=0 & goto x4 :x6 if !a:~%b%^,1!==!d! set /a n+=1 if !n! equ 2 set /a b+=1 & goto x7 set /a b+=1 & goto x6 :x7 set s=!s!!a:~0,%b%!!e!& set /a b+=1 set a=!a:~%b%!& set /a b=0 & goto x4 :x8 if defined s set s=!s:~0,-1! endlocal & set %1=%s%
>>620 パスに全角半角含むかどうかに関わらず
a.pngがNG
a - コピー.pngがOK
あ.pngがNG
>>622 すみません。:x3 の下の行を下記に訂正します
:x3
set a=!a:~%b%,-1!!e!& set /a b=0
>>598 IT土方してるけどいまだにVB6のメンテ案件がたくさん来る (・_・;)
古いシステムを使い続ける企業って多いんだなあ
リダイレクト使ってバッチ内に記述したテキストをファイルに出力すると、行数が増えるにつれて どんどん処理が遅くなるんですが(多分ファイルのオープンとクローズの処理が重たい んだとは思うけど)、何十行もあるテキストでも一括で書き込んで早くする方法とかないですか? ただ不思議なのは、ソースとなるテキストを別のテキストファイルからforで読み込みして 各行を逐次出力ファイルにリダイレクトで書き出した場合はそんなに遅くないんですよねぇ。
>>626 俺はそう思ったことはないなぁ…具体的なコードを見せて。
一括での書き込みは、処理をカッコで括るとできる。
(
echo start
:
:
echo end
) > test.txt
>>627 コードといっても何も特別なことはしてないんだけど、何十行というのは嘘で 当該箇所確認してみたら実際には何百行もありました。 ----- sample1.bat echo [%time%] 開始 type nul > "D:\tmp\out-file.txt" echo hoge>> "D:\tmp\out-file.txt" echo hoge>> "D:\tmp\out-file.txt" ~延々と600行近い繰り返し~ echo hoge>> "D:\tmp\out-file.txt" echo hoge>> "D:\tmp\out-file.txt" echo [%time%] 終了 exit /b ----- これで大体3~4秒くらい。実際のコードは文字列も長いし、 途中条件式が入ってたりするのでもうあと1~2秒ほど長い。 前の投稿で「forで回してリダイレクトした方が何故か早い」と書き込んだけど、勘違い。 改めて確認したらほとんど変わらなかった。 >>627 ----- sample2.bat
echo [%time%] 開始
type nul > "D:\tmp\out-file.txt"
for /f "usebackq delims=" %%L in (`findstr /n .* "D:\tmp\hoge-source.txt"`) do (
set str_temp=%%L
call :redirect-loop
)
echo [%time%] 終了
exit /b
:redirect-loop
echo %str_temp%>> "D:\tmp\out-file.txt"
exit /b
-----
教えてもらった全体を()で囲ってまとめてリダイレクトしたら一瞬で処理完了しました。ありがとうございます。
実際のコードは条件式の他に変数展開した文字列の中に()が含まれていたりするので、要所要所で使い分けが必要そうですが。
>>628-629 あー、600行もあったらファイルのオープン・クローズ処理の影響が大きくなるねぇ。
カッコで括ると「括った内容、1行で延々書かれたものとして処理」してくれる。多分こういう用途のためにあるんだと思う。
なのでカッコ内の特殊文字エスケープは通常と変わらなかったはず…。(確証はないけど)
俺はヒアドキュメントっぽいことがしたい時、いちいちリダイレクトを入れるのが面倒&読みづらいこともあってこう書いてるわ。
>>629 別のバッチファイルにするのは駄目なん?
call b.bat >file
なら()の処理とか不要では。
別のバッチファイルにする必要も無いんじゃね? @echo off call :abc > d.txt goto :eof :abc echo xxx echo yyy echo zzz
ちょっと聞きたいんだが… for /f "tokens=1* delims=:" %%A in ('findstr /n "^" filename.txt') do echo.%%B これ、バッチが標準入力から受け取ったものを処理する雛形らしいんだけど… findstr /n "^" これアリか?正規表現として成立してない!?何だこれ?? findstr /n ".*" ならアリだしこう書くべし。正規表現として何でもマッチする。 なんだけど何で findstr /n "^" が通るのか分からんわ。
>>635 findstrはあくまで検索パターンにマッチする行全体を返す。
行頭文字があればマッチと判断するんだな、たぶん"$"でも通るんじゃね?w
>>636 https://blogs.yahoo.co.jp/kerupani/15344574.html が上手いことやってる。感心した。万能ではないらしいが検証中。
tee が作れるかもしれん。
>>637 マジだった。findstrはアホの子だった。
あー、もっとも、find /v "" が空文字列にマッチする時点で駄目ではある。
>>635 正規表現としてじゃなくて cmd のエスケープかと。
echo;abc | findstr /n ""
FINDSTR: 検索文字列がありません。
echo;abc | findstr /n "^"
1:abc
>>641 ^ の左側に " があるので ^ はただの文字
プロセスが特定の文字列を出力したら処理を終了させたくて下記のようなの書いてみたけど思うように動かないです。 process.exe | find "hoge"&&TASKkill /F /im process.exe &&で指定したコマンドは元のプロセスが終了しないと実行されないのでしょうか?
>>643 多分、process.exeが終了しなくても、標準入出力をクローズすればパイプは渡ってくるんじゃないかな?
>>643 リファレンス読めよ。
&&を何かに変えれば多分動くぜ。
& コマンドの連結 && 前のコマンドの実行結果が正常(ERRORCODE=0の場合)に後ろのコマンドを実行する || 前のコマンドの実行結果が失敗(ERRORCODE>0の場合)に後ろのコマンドを実行する
ERRORLEVELだったよ あと、環境変数は実行前に展開されるため、前のコマンドで設定した値を後ろのコマンドで参照すると思わぬ結果になる for文での注意と同様で、遅延環境変数を使うとかすれば大丈夫だが また行を分ける場合に%errorlevel%を使うなら参照だけにすること (設定すると単なる環境変数として扱われる) あと、そもそも前のコマンドが終了してないのにパイプにデータが渡ってくるのかも要確認
レスありがとうございます 標準入出力をクローズというのがちょっと分からないんですがどのようにすればいいのでしょうか?
process.exe に標準入出力をクローズさせるんだよ
そんなことするぐらいならvbsのExec使えばいいと思うの
>>649 >>644 >>650 の言ってることは戯言だから気にするな。
process.exe が終了したら勝手にクローズする。
終了してから TASKkill しても見つからんエラーが出るだけで無意味
リダイレクトしてテキストファイルに出力しながらstartで立ち上げた別のbatにfindして貰う事で解決しました。
>>652 process.exeってのが自作の場合、そうしろってことだろ
Linuxでコマンド実行した結果とWindowsでコマンド実行した結果を
一つのファイルに書き出したいんだけど、改行コードが違っている
バッチファイルでCR LFではなくLFで出力したいなと思って
このコードを見つけたんだが何やってるのかさっぱりわからない
<NUL set /p=message が set /p=message <NUL と同じ意味で
「メッセージを表示してユーザーの入力内容を変数に入れるコマンド」の
代入先変数の省略 + 入力内容省略 = 改行なしecho
ということはわかったんだけど、^%LF%%LF% がなんなのか
なんでこれでうまく動くのかわからん
https://stackoverflow.com/questions/9876370/echo-line-to-a-file-on-windows-with-a-unix-linebreak SET LF=^
REM important to have two blank lines after the SET command
<NUL set /p=test line^%LF%%LF%> t.txt
違うこと調べていて、たまたま答えにぶつかったぜw
http://ken sou1900.blog96.f c2.com/blog-en try-7.html
違うこと調べていて、たまたま答えにぶつかったぜw http://kensou1900.blog96.f c2.com/blog-en try-7.html > キャレット(^)直後の文字がLFの場合は特殊な動作になる。 > キャレ ット(^)の後ろにLFがある場合、そのLFは削除され、 > 次の文字がエスケープされる。不思議なことにキャレ ット(^)の後ろにLFが2つ続く場合は、 > 前のLFは消えるが、後ろのLFは通常の文字のように扱われる。 > この動作を使ってLFをコマンドに渡したり、変数名や変数の値に使用することができる。 > > LFがエスケープされた場合、バッチファイルの続 きを取り込まないといけなく なる場合がある。その場合、1.から3.が再度行われるようだ。 set /p=test line^[LF][LF] これはこの部分だな > 不思議なことにキャレット(^)の後ろにLFが2つ続く場合は、 > 前のLFは消えるが、後ろのLFは通常の文字のように扱われる。 単なる不思議な動作か。なるほどな! SET LF=^ REM important to have two blank lines after the SET command こっちも未だよくわからいが、 まあこれも単なる不思議な動作だろう なっとくした ↑これは書き込めるのか ↓これはどうだ? a.fc2.com
aaaablog96.fc2.com とかいう文字が書き込めないみたいだな
aaaablog96.fc2.com/aaa.html
よくわからん aaaablog96.fc2.com/blog.html
よくわからん aaaa.blog.fc2.com/blog.html
面倒くさいから今度からURLは全部短縮URLを使おう
改行は[LF]じゃなくて[CR][LF]だと思うんだが、どうなんだろう?
Windowsの改行コードは[CR][LF]だよ だけど、処理の一部として、Linux側にコマンドを投げ その出力をログファイルに書き込むんだよ Linuxの改行コードは[LF] その同じログファイルにWindowsからも書き込むんだよ こっちは当然[CR][LF] まざるとうざくなるので、どちらかに統一したかったんだよ
Winでもコンソールは何故かLFだよ 混同すんなよ
>>671 コンソールがLFって意味わからん。
改行コードをどう出力するかはコマンド次第だろ
Windowsはデフォルトの改行コードがCR LFだってだけ
それに従わないプログラムもあるよ
(例 nkf は出力改行コードを変更できる)
PSでもcmdでもいいんだけど一行で文字列+連番を出力できない? echo aaa + (1..10) とかやると別々に出ちゃう
>>673 for /L %%i in (1,1,10) do echo aaa %%i
>>673 いまいちよくわからんけど abc1 abc2 abc3 abc4 … って言うのが欲しいの?PS なら
[String]::Join(' ', (1..10 | %{ "abc$_" } ))
でいける
>>674 ありがとう、でもエラーでうまく動かなかった
>>676 完璧です
助かりました
>>671 CRTがテキストモードの時にはCRを足してくれてるんだよ?
改行コードはコマンドに依存する dir /? > d.txt sort /? > s.txt
質問です ファイルをbatファイルにドラッグアンドドロップしてファイル名等を得たいのですが 2番目のドライブ名+パス名(ファイル名以外)が表示されません (%~dpと表示される) どう記述すればいいのでしょうか もう2時間悩んでおります echo off for %%f in (%*) do ( echo %%f echo %%~dp echo %%~nf pause )
>>681 ありがとうございます
それも試したと思っていたけどそうでなかったようですね
>>682 多くのサンプルではサブルーチンをつかっているようですが
カッコを使うとバグの原因になりやすいとかそんな理由なのでしょうか
>>683 %%~dp → %%~df%%~pf
callを使い %1などを使えるようにするため
昔は%~n1 など数字でないと動作無保証だった
Win10のコマンドプロンプト画面では改行と折り返しを区別してコピーできるようになったね。これすごく便利。 他に改善点とかあるのかな?
コピペでCtrl+C,Ctrl+Vも使える
Alt+Enterで最大化
ウィンドウスナップ
など。詳しくは
https://japan.zdnet.com/article/35069776/ windows板のスレに書いてしまったので詳細はそちらを参照して頂きたいのですが
http://2chb.net/r/win/1381119881/327 この件について詳細をご存知の方あるいは解説されているサイトをご存知の方は
ご教示頂けないでしょうか?
再現しない。よくソース見直してみて おそらく単に遅延変数展開だけの問題に見える。
プログラムを問題の箇所だけ抜き出して実行しても同じ結果になります。 xxxを未定義状態にしてから%xxx%を引数にして実行するとやはり 「echo %aaa%|more」の結果がyyyと表示されます 当方の環境はWindows7 SP1です これはこう動作するように作られた仕様なのかそれともあてにならない不思議動作なのか cmdのバグなのか判断したいです
ん?せやで?Windows 7はデフォルトの設定が違うんやで しらんかったんか?cmd /?とかしてみな。
cmd /? にも setlocal /? にも echo /? にも echoとパイプ併用時の環境変数の二重展開について記述は無いようです
別のものを見ているのかもしれません。 そちらには何と書いてありますか?
パイプってCall文でサブルーチン処理してるような物だし、call文と同じ展開をすると思っとけばいいんじゃね?
なるほど。 では逆にあえて二重展開したい場合はcallを使ったほうが無難でしょうか?
call文で変数内変数が1ネスト展開されるのはパイプよりは有名だと思う
一番知られて無いのが、for /f文の('コマンド')が同じく二重展開されるってのかな
いや本当は、コマンドの中で^を付けてエスケープしないといけない場合があることは 結構知られているんだけど、それが二重展開のせいだってことが認識されてないわけで
echo は結構罠 if "%errlorleverl%" ... も罠。 はやくバッチから救われたい…
こういうことじゃないかな? set ERRORLEVEL=0 hogecommand if %ERRORLEVEL% gtr 0 goto :ERROR これが絶対真にならず、ジャンプしないとか
エラーは1以上とはかぎらないんだよな、コマンドによっては。
>>703 echo hoge > test.txt
て書くと「hoge」の後の半角空白までがtest.txtに出力されるんだよ。
>>704 代入しなくても、errorlevel を環境変数として判定に使うと正常に動かない場合がある。
具体的には
echo n | comp A.exe B.exe >NUL 2>&1
if not "%ERRORLEVEL%"="0" (
:
このとき、何故か%ERRORLEVEL% は常に「0」。バイナリ不一致でも「0」。
echo n | comp A.exe B.exe >NUL 2>&1
if not errorlevel 1 (
:
だと正常に動く。何故だか分からない。
>>706 にちょっと間違い。
〇 if "%ERRORLEVEL%"="0" (
× if not "%ERRORLEVEL%"="0" (
>>708 悪い。typo。
〇 if "%ERRORLEVEL%"=="0" (
何故か以前にいろいろ間違いすぎなんだよ ゼロから書き直せ
>>710 > ゼロから書き直せ
こんな感じっすかー?
0" ([HOME]if "%ERRORLEVEL%"=="
>>704 >>706
ERRORLEVELは代入すると返却値として使えなくなるんじゃ
なかったっけ?
だからやるならば
set ERRORLEVEL=
だけにしないとだめなのでは
ただ、これをやってバッチ内でERRORLEVEL環境変数の
初期化みたいなことしてもうまく動かないこともあったような
気がするけど何か勘違いしてるんだろうな
>>706 パイプの動作が原因だろう
パイプの右側は子タスクでの実行となる(おそらくは)
メインタスクに環境を引き継がないんだと思う
echo "a"|for /f %%i in ('find "a"') do set x=OK
echo.%x%
これで%x%には値が入らない
echo "a"|find "a"&set x=OK
なら%x%にはOKが入るが
echo "a"|(find "a"&set x=OK)
では%x%にはOKが入らない
>>713 下2つ&は&&の間違いだが、別に&だろうが&&だろうが(この場合の)結果は変わらない
setコマンドの長いヘルプの下の方に 「ユーザーがこれらの名前の変数を明示的に定義する場合、 その定義は下記の動的な定義を無効にします。」 と書かれてる。errorlevelをsetするのは回避した方がいいだろう
ついでに言っとくと パイプはデータの受け手が子タスクになったけど for /fの'コマンド'は送り手が子タスクになる 従って、'コマンド'の中で環境変数に値を入れても、メインタスクには引き継がれない
>>710 難癖付けてばかりで話題提供もできない人はゼロから人生をやり直した方が(ry
>>713 んー、俺はもうそこまで調べる気もなくてね…ほぼ諦めてる。
子タスクとかどこの文献見ればあるんだろう?
あってもなくても、んなテクニック、引継ぎできる代物でもあるまい…。
例えば、
type data.txt | cscript //nologo hoge.vbs
if not errorlevel 1 (
:
これも実は…駄目なのだ!!
VBScript側で Call WScript.Quit(1)
で抜けられれば引っかかるが…
想定外の変なデータを食わされてランタイムエラーで落ちた場合には引っかからない。
cscript はスクリプトエンジンだから別物扱いしとこ…てなところで。
hoge.vbs が正常終了する直前に success.txt を空で作るようにしといて。
del success.txt
type data.txt | cscript //nologo hoge.vbs
if exist success.txt (
:
)
del success.txt
こんな感じにするしかなかったし、これならせめて引継ぎができると思う。
あ、ごめん。 if not errorlevel 1 ( 正常終了処理 ) else ( 異常終了処理 ) て書くべきだった
勉強になる話題だけど、バッチファイルは言語仕様の規模に比して闇が深すぎると思う
>>721 そだね
だんだんとwslの利用者が増えていくのだろうな
>>719 子タスクと言ったのは俺の推測(想像)でしかないから
データの受け渡しを行うのには、送り手と受け手の両者が存在しないと変だろうってことからね
あと、タスクというのも、適当な概念だから
親の環境を引き継いで生成された子環境のことね
実体はスレッドだろうと想像するけど
>>703 綴りといえばenabledelayedexpantionも罠レベルだよ・・・誰だこれ考えたの('A`)
元の英語がわかれば enable delayed expansion を繋げただけなんだよ
質問させてください。 Linuxでいうところの、/dev/nullで標準入力待ちを終了させるのはどうすればいいのでしょうか。 具体的には、Windows向けのopensslコマンドを実行しています。 openssl s_client -connect ~とやると標準出力が一通り出たところで入力待ちになる仕様で、 コマンドプロンプト上だとCtrl+Cで止めてあげる必要があります。 Linuxだと、末尾に< /dev/nullで終わらせられるのですが、Windowsバッチで同じように終了させる方法は無いでしょうか。
>>728 書いてなくてすみません。それだとダメでした。
>>730 参考サイトありがとうございます。
先ほど教えていただいたのと同じ< nulですよね。
サンプルコマンドの通り打ってみても入力待ちで止まります…。
念のためOpenSSLを入れ直しても変わりませんでした。
サンプルでパイプで渡してる直前まで( < nul 2> nul)で試すと、
実行結果がダーっと出て、入力待ちで止まるんですよね…。
下のサイトのやり方も参考にしつつやってみましたが、どれも結果は変わらずでした。
後出しですみませんが、当方の環境はWin10 Pro 1803、opensslは1.0.2m.1.0.2oでやってました。
https://stackoverflow.com/questions/25760596/how-to-terminate-openssl-s-client-after-connection 回答くださった方、ありがとうございました。
もしやってみて、何言ってんだ、できたぞ?という方いらっしゃいましたら教えていただければ幸いです。
制御文字を入力できるエディタ(サクラエディタ等)で バッチを開いて nulの代りに[0x03]か0x04の制御コード入れてみては?
>>732 普段OpenSSLは使わないけどたまたまインストールしてあったOpenSSL 1.1.0hで出来たよ
コマンドはこう
openssl s_client -connect example.com:443 < nul 2> nul | openssl x509 -text | findstr Not
>>734 試していただいてありがとうございます。
そのコマンドを実行したときなのですが、コンソールが返ってくるまで1分ほどかかりませんか? すぐ返りますか?
< nulの有無に関わらず1分ほど待つので、単にタイムアウトか何かで終了しているのかなと思っております。
nulを入力として受け取っているなら、すぐに1個目のパイプより前のコマンドは終わるはずだと思いまして…。
>>736 ありがとうございます。
ということは
>>728 さんと同じ書き方でちゃんとできて、
私の環境起因で何かがおかしいってことですね…。
他のパソコン出してきて試してみようと思います。
>>733 さんもありがとうございます。
まずはバッチ化する前にプロンプト上で試している段階で躓いてました。
>>733 1)コマンドプロンプトで下記のように入力し、hoge.txtを作る
copy con hoge.txt[Enter]
[Ctrl+d]
[Ctrl+z]
2)バッチの方で
<hoge.txt
とすればコンソールでCtrl+Dを入力したのと同じ効果となるはず
>>737 です。
あの後うまくいきました!アドバイスありがとうございました!
Windows向けに提供されている最新のインストーラを色々試したのですが、
openssl 1.0.2pだとダメ、1.1.0iだと< nulが効きました。
32bit向け、64bit向けのインストーラのどれでも同じ結果でした。
私の試してたのが1.0.2系だけで、
>>734 さんは1.1.0hで成功してるので、
1.0.2系だとダメなのかもしれません…。
< nulはきっと汎用的なものなので、そんなわけはないと思いたいのですが…。
長々とありがとうございました、大変助かりました。
悪いけど、Windowsバッチに鉄板を求めるのも、追いかけるのも無駄。 歴史的経緯でそうなってしまっている。マトモな資料なんかありゃない。 NULの解釈がコマンドによって違ったって全く不思議じゃあない。 犬のクソをクソだと知りつつカリントウだと思いながら食わなければならないような、そんな代物。 好きで書いてる奴なんかほとんどいないと思う。 バッチで書いた方が良いと判断できる材料がなければVBscriptやPowerShellで書いた方が遥かにいい。 環境が許せば他の言語の導入を検討するのも大いにいい。 よく知られたコマンドをよく知られたイディオム下で使うのでもなければ、バッチでなんか書かない方がいい。 それでもクソみたいにハマることがあるんだから。
UNCパスを一向に解釈しないのがとにかく糞だと思う
xcopy のヘルプは酷い。 Vistaでは「推奨されない。使わないで。robocopyを使って」みたいな文言が出てきた。理由は記述なし。 この文言、7以降では消えた。 ネットワーク越しにxcopy中に通信が切れたらどうなるか、MSは知ってたはずなんだが。 xcopyを使いまくってるクソベンダーどもから「直しきれない。フザけんな!」とでも突き上げを食らったんだろうか? こういうところも本当に信用できない。
>>741 cmd「あ、pushdとかでヨロ」
ネットワーク系で言えばpingが酷い。
if errorlevel そのものが効かない。エラーしたらズルズルっと抜ける。
あ、某SIer(富〇通)のバッチを思い出した。
pingでTCPの疎通確認?エラー処理なし?
バッチとか以前の問題だった。
富〇通は日本から消え去ればいいと思った。
おいおい、さっきからレスに「ドット・エグゼ」を半角英数で書くと弾かれるようになってるぜ… なんだいこりゃ。
標準入力から読むんじゃなければ <nul なんか無意味だろうに...
pingは標準エラー出力の文言で処理するのが慣例だろ...
すみません、CMDを最近やり始めたのですが ネットで検索すると%Aと%%Aのように「%」が1つ付く場合と2つ付く場合があったのですが どういう違いがあるのでしょうか?
>>749 %Aはfor文内でのみつかう変数。for文をコマンドラインから直接実行する場合は%A
バッチスクリプト内で記述する場合は%%Aとする。
for /? (またはhelp for)
で表示されるヘルプの上の方に書かれている。
batファイルで任意のプログラムを実行し、一定時間後に強制終了させる(画面を閉じる)という処理は実現可能ですか? 任意のプログラムも同じDOS画面上で走ります。 タイマーでtaskkillを実行してcmdを終了させるというのを考えたんですが、cmdが複数あると使えないので他に方法があれば知りたいです。
>>751 START "test001" cmd /c test.bat
TASKKILL /FI "WINDOWTITLE eq test001"
>>747 否。
pingはICMP。pingが通ってもTCPが通るという保証は無い。
逆に、pingは返さないがTCPが通る環境だってある。
ただでさえpingコマンドの動きはおかしいのに、pingでTCP疎通確認しました!というのが大手SIer(富〇通とか)が首を釣るべきポイント。
ダミーの共有フォルダを用意して
dir \\hoge.local\hoge
とかでSMBを経由したTCPの疎通が確認できるんだぜ??
頭が悪いとしか言いようがない。
もう一度言う。
pingではTCPの疎通は「絶対に確認できない」
言っとくけど、LinuxのpingでもTCPの疎通は確認できないからな。分かってると思うけど。
>>754 そんなこと言い出したら特定のホストや特定のポートだけは通さないとかあるからモノホンの通信でないと確認なんて取れんわ
富〇通から何されたのか知らんけど富〇通に同情するレベルのバカ
プロトコルが別物というのはその通りだな、 コマンドプロンプトでのエラーハンドリングの話かと思ったわ(分かっちゃいるとは思うが)
>>754 わなくらい以降、SMBを通すようなネットワーク組むような業者はやばいだろ
このスレは1年半前に立ってまだ760レスぐらいですが ここ1ヶ月半で見ると200レスぐらい書き込みがあるので CMDの人気が出てきたということでよいのでしょうか?
>>756 富〇通のシステムのサーバーがシステムの動作に必要なファイルを共有フォルダで端末に公開してたからだよ。
「何でこうしないの?」だよ。アホか。
>>758 そこまで知らねーな。
SMBoverTCPを止めてWindowsの共有フォルダが機能しなくなるかどうかのテストまでしたことはない。
止まるらしいけどバッチの範囲内じゃなくなるからこの話はもうしない。
>>761 > 富〇通のシステムのサーバーがシステムの動作に必要なファイルを共有フォルダで端末に公開してたからだよ。
> 「何でこうしないの?」だよ。アホか。
全然違う話ししだして笑う
>>762 1. 富〇通のシステムは、端末の起動時にサーバーにTCPの疎通確認をする。それがただpingを打つ「だけ」。通ろうが通るまいが処理を続行。意味がない。
2. 俺はこう思った。「端末が見に行く共有フォルダをdirしてエラー検出した方が確実でしょ?何でこうしないの?」
て言わなきゃ分からないアレですか?
つまりイントラネットなわけね ならpingが通れば回線チェックできるとしても問題なかろう 鯖がpingを許可してるシステムだろうし
>>764 おい。
十歩くらいは譲ってやる。
だがお前は馬鹿。
問題。
Windowsサーバーはネットワークの場所の検出に失敗することがあります。
パブリックと勘違いしたらpingを返さないことがあります。
さて、検出に失敗する場合はどのような場合でしょうか?
答えではないが発生例
富〇通に渡された手順通りにサーバーを再起動したらそうなった
> ならpingが通れば回線チェックできるとしても問題なかろう
pingの結果だけを信用したら駄目なんだよクソが!!
どんだけレベル低いんだお前??
…ああもう呆れる…。
んー、バッチだけじゃなくてWinの挙動も関係すんなぁ…ネットワーク系は。 まあいい、また今度な。
あ、答えはTechNetとかに載ってるから興味ある人はてきとーに調べといて。 英語だけど。
>>765 パブリックと勘違いしてるなら、それはpingでも検出できるじゃん。
絶対に正しい自分の主張を認めてもらいたいだけの人なんだから相手しても意味ないでしょ
昔はpingを使っていたが、今は set errorlevel= arp -a|findstr 192.168.0. >nul if not %ERRORLEVEL% == 0 goto オフライン処理
>>763 本当に頭悪いんだな w
いきなりdir \\hoge.local\hogeが失敗しただけだと何が起きてるのかわからん
pingが通ってるかどうかで障害の範囲がある程度絞れる
ちょっとしたシステムだとネットワークとサーバーで違うベンダーが構築してるとかあるからどっちを呼び出すかの切り分けに使ったりする
ping ホスト名 で打ってるならその端末がWINS名前解決出来てるかは分かる でも「TCP疎通」ってタームはたしかに違和感ある。某省庁案件で富士通のインフラ部隊と仕事したが、そんなターム使って無かったけどな...
ネットワーク=TCPみたいに言ってる奴は見たことあるな たいてい文脈でわかるからいちいち指摘なんてしないけどね
ただの記号ですら言い方は人それぞれだからなあ ピリオド : ドット、ポチ、ポツ アスタリスク : アスター、コメ、ピカ アンダースコア : アンダーバー、アンスコ
>>768 パブリックと誤検出した場合、当たり前だけどpingは返さない。
ドメインコントローラーが勘違いした場合、端末も勘違いすることがある。
クソな再起動手順がもたらす問題を回避するために…「全プロファイルでファイァーウォール停止」を要求されたらそりゃたまらんわ。
正しい再起動手順でやれば、そんな事態は一切おこらないってのにさ。
>>771 おまい、スレ違い。
ここはバッチスクリプトスレ。
過不足ない通信が可能かどうかを調べるバッチなりなんなりを使うのが主題。
実際にエラーが出て連絡を受けた人間が調査の手始めにpingを打つことは普通にある。
>>772 ???WINS名前解決???
何世紀の人????
「少なくとも、相手がTCPを使ったサービスを実行できる状態にある」の言いに使ってるけどね。間違いじゃないだろ。
本当に相手のサービスそのものがダウンしているかどうかにはtelnetを使ったりするし。MS純正じゃないのも含めて。
でもまぁここはバッチスクリプトのスレなので、pingが通った=TCPもイケる、は間違いなのは別で調べて頂戴。
>>770 arp -a って…ギャグのつもりなのか?笑えない。
pingが通る=回線が正常に繋がっている(途中で断線してない) だろ
ところでSMBはWINS使ったっけ? NBT(NetBIOS over TCP)じゃなかったっけ
はなし逸れるが、今の現場は大手の保険会社なのに10BASE-Tとかで驚くわ 20年間変わってないのかコレ? まあ俺はしがない派遣IT土方だが
>>782 そんなもんだよ
不都合が生じないと変えないのと普通
>>781 WINS と NBT はレイヤー違うぞ
if スクリーンセーバーが起動されていなかったら if 各種省電力モードになっていなかったら if モニタの電源が消されていなかったら if モニタの前に人が座っていたら できる範囲でいいのでこれらの判定方法を教えてください
pauseすれば人が見てるかどうかは判定できるが、 立っててもいいから駄目だなあ。
モニター叩き割ると多分全部常にfalseになるから解決できると思う
findstr はアホの子と言ってすみませんでした。 「^」や「$」は位置にマッチするメタ文字でした。 お詫びと訂正を申し上げます。 別件で、find /v "" が空文字列にマッチする件は納得いかないため調査中です。
findstrは対象文字コードの異なる場合のテキスト検索が難しい。 chcpして、バッチ自体の文字コードも合わせても、リテラルの検索パターン指定だとダメ。 そんな場合はpowershell Select-String でやると良い
バッチファイルで上の階層に移動し そのカレントディレクトリを変数に格納したいんです。 現在の記述 cd ../ set PARENT_DIR=%CD%\ これを一行にまとめる方法ってありませんかね? for文やパイプラインを使っても駄目でした...
難しく考えすぎ、単純に&&か&で繋げばいんじゃね?
>>793 cd .. &for /f %a in ('cd') do set parent=%a
でできた
遅延展開でfor文ループをやってるバッチファイル(*.bat)があるんですが このバッチファイルをメモ帳で開いて内容をクリップボードにコピーして それをコマンドプロンプト画面に貼り付けたら同じように動作しますか?
なんか初歩的やなあ。 遅延展開だから最初にsetlocal enabledelayedexpansion を書かいて&で繋げて次のコマンドを書ける。ただし%%は%に置き換える必要がある
やってみればわかるけどコマンドプロンプトで setlocal enabledelayedexpansionやっても効果ないよ。 cmd /v:onで遅延展開有効にしたコマンドプロンプト起動しないとだめ。
ああほんとだ。こんな感じにすればいいのね cmd /v:on set str=hoge &for /l %a in (0,2,10) do ( set str=!str!%a ) & echo !str!
800! このシリーズも、12まで言っても、新発見があるのね。 前(バッチファイルプログラミング質問スレ )のも含むと、すでに15スレ目か。
自分はこのスレになってから来たからまだ新参、過去スレ読まなきゃ
>>798 > バッチ ファイルでは、SETLOCAL ENABLEEXTENSIONS または DISABLEEXTENSIONS
> 引数は /V:ON または /V:OFF スイッチよりも優先されます。
> 詳細については SETLOCAL /? を参照してください。
じゃない??
cmd /v:on なんて使ったことがない…
あ、もしかしてバッチとコマンドプロンプトでは動きが違うってこと??
>>797-799 ええと、よくわからなくなってきたので自分でもググってみますね。(^_^;)
どうもありがとうございました。
ググらずにコマンドプロンプト開いて試せばいいんだよ ・遅延展開を使うために事前に cmd /v:on[Enter]する ・バッチのfor文は%%を%1つに置き換えてから貼る。 ・do ループの処理は複数行で書けないので、( 処理 & 処理 & 処理 )と書く。(の後と)の前の半角スペースが大事 とりあえずそんなとこ。
コマンドプロンプトでもdo の後に括弧つけて改行すれば More?ってプロンプト出て普通に複数行書ける > for %x in (hoge) do ( More?
SETLOCALに ENABLEEXTENSIONSなどがあったのか、知らなかったなあ setlocalcのようなものが必要なこと自体cmdの設計ミスなんだけど、ますます複雑化、恥の上塗り路線
>>808 for %%i in (.) do set PARENT_DIR=%%~dpi
forとか使わなくても… %cd:\=&set parent=% って知られてないんかな?
for %%i in (..) do set PARENT_DIR=%%~fi
テキストを type でユニコードに変換できるけど cmd /u /c type sjis.txt > uni.txt これを逆にシフトjisに戻す方法はありますか?
cmd /a /c more < uni.txt > sjis2.txt
cmd /u /c type s.txt > u.txt set /p x="" < nul > bom.txt copy /b bom.txt + u.txt u2.txt type u2.txt > s2.txt comp s.txt s2.txt
nkf 推しは死ね。
それはなんでもアリじゃねぇか。
とりあえず、ここは「(デフォでは)全Windows環境で動く」が前提にしろや。
>>817 それが何故上手く動くのかの解説をする義務が君にはあると思う。
「ここのコマンドでSJIS変換が入ってます」くらいの。
上記の2バイトのBOMはユニコードのテキストである印です。 例えばメモ帳で空のユニコードのファイルを作成したらbom.txtと同じになる。 typeコマンドはBOMを参照して入力コードを決定し、 コードページを参照して出力コードを決定する。
>>819 ありがとう。。
> typeコマンドはBOMを参照して入力コードを決定し、
type にそんな機能があったのか!という感じ。
応用すれば色々と変換できる ソースが EUC-JP の例 set /p BOM="" < nul > UTF-16LE.txt chcp 20932 cmd /u /c type EUC-JP.txt >> UTF-16LE.txt chcp 65000 type UTF-16LE.txt > UTF-7.txt chcp 65001 type UTF-16LE.txt > UTF-8.txt chcp 50222 type UTF-16LE.txt > JIS.txt chcp 932 type UTF-16LE.txt > SJIS.txt 泥臭いのが好きな人はどうぞ 改行コードは知らんw
本筋とは関係ないんだが、『2バイトのBOM』のあるレス
>>817 ,822 読み込むと
しばらくしてと JaneStyle(3.75) が落ちる
dat から該当部分『2バイトのBOM』を削除すると問題なくなる
今どき JaneStyle 3.75 使ってる人はほぼ居ないと思うけど参考まで
オマ環だったらゴメンナサイ
俺の環境は Win10 で Jane Style Version 4.00 不具合無い
>>823 専ブラをバージョンアップしない理由は何?
>>823 3.75でこのスレを串(API)で読み込んで10分ほど放置、その後新着チェックや別スレを見ても別に落ちたりしないんだが
(なお、HTMLで読み込むとBOM部分が削除されちゃったんで意味なし)
どうやら
>>822 のBOM="" の引用符の中は
Internet Explorer 11 ではコピペ出来ないようだ
該当の行の Base64 は
c2V0IC9wIEJPTT0i//4iIDwgbnVsID4gVVRGLTE2TEUudHh0DQo=
>>825 プロキシ入れる必要はあって問題なくはないけど読み書きに使えてるから
広告非表示するだけならバイナリ弄る方が手っ取り早いとは思いますが、そんな感じです
>>826 ありゃ、そんな気はしてましたがオマ環でしたか
もうちょっと確認してみると、MacType を切ると再現しなくなったので、
その辺の合わせ技+こちらのその他の環境、かなと
読み込んであのレスのあたりをスクロールして上下させてると、
フォントの描画が MacType が効いてないようになってから100%落ちちゃってたもんで
>>828 俺もmactypeは入ってるんだけどなあ
なお10回程スクロール(キー、マウスホィール、スクロールバー)してみたんだけど
MacTypeは関係ないのでは? 4.0でなんともないし
確認ありがとうございます 限定的な環境依存のいわゆる、オマ環、と分かっただけでも収穫です 流石にスレチと思うのでこの辺で
>>822 のBOMの引用符の中を正しくコピペ出来ない人は、
1行目をこれで代用
chcp 65000
cmd /u /c set /p BOM=+/v8<nul> UTF-16LE.txt
>>833 がうまくいかない
バイナリエディタでできたUTF-16LE.txtを覗くと
2B 00 2F 00 76 00 38 00
となる
よくわかんないんだけど BOMはUTF-16LEでは "FF FE" じゃないの?
>>834 chcp 65000が利かないのかな?環境は2000? XP?
こっちではどうかな?
for /f "tokens=1,2 delims=[" %%i in ('cmd /u /c echo 寿対') do set xFF=%%i&set xFE=%%j
set /p BOM=%xFF%%xFE%<nul>utf16le.txt
>>837 バッチに
>>830 を書いて実行したら FF FEになった。
コマンドプロンプトで1行づつやってたからダメだったらしい
>>837 もバッチで大丈夫でした
Win10です
setlocal enabledelayedexpansion set a=a set b=A if /i %a% == %b:~0,1% echo eq1 if /i !a! == !b:~0,1! echo eq2 set c=!b:~0,1! if /i !a! == !c! echo eq3 if /i %a% == %b% echo eq4 if /i !a! == !b! echo eq5 結果は eq1 eq3 eq4 eq5 何故か eq2 が出ない
setlocal enabledelayedexpansion set a=abc if /i !a:~0,1! == !a:~0,1! echo eq 1! の使い方が誤っています。 俺の PC だけなのか?
分かった ^, にしたら良かった if /i !a:~0^,1! == !a:~0^,1! echo eq
また謎です shiftすると%1は変わるが、%*は変わらない
表示は出来るが、代入が一部だけ出来ない整数値があったよ @echo off setlocal enabledelayedexpansion set /a "a=1<<31" set /a b=a set /a c=%a% set /a d=!a! echo a=%a% echo b=%b% echo c=%c% echo d=%d% pause 結果は a=-2147483648 b=-2147483648 c= d=
setlocal enabledelayedexpansion set /a "a=1,b_!a!=2" set b_ で、 b_0=2 何か変だが、こういう仕様なのか?
,で分けてあってもsetコマンドは1つだけなので複数コマンドとは思われてないってことなんだろうね setlocal enabledelayedexpansion set /a a=1 & set b_!a!=2 set b_!a! なら大丈夫
>>846 ありがとうございます
!a! は set /a 実行直前の値でした
setlocal enabledelayedexpansion
set /a a=0
for /L %%i in (1,1,3) do set /a "a=%%i,b=a,c=!a!,d=%a%" & echo !a! !b! !c! !d!
1 1 0 0
2 2 1 0
3 3 2 0
setlocal enabledelayedexpansion set /a a=0 for /L %%i in (1,1,3) do ( set /a a=%%i &set /a b=a &set /a c=!a! &set /a d=%a% &echo !a! !b! !c! !d! ) なら 1 1 1 0 2 2 2 0 3 3 3 0 となる。 bへの値代入が!抜きのaでできるって知らなかったわ… 謎挙動。
set /a で %a% や !a! はあまり使用しない方が良さそうだ
% や ! は演算子に含まれる文字で紛らわしいし
展開のタイミングで予想外の挙動するし
展開時に
>>844 のように特異値でエラーになったりするし
値参照は変数名だけでいい
ご自由に。それより某グラマー御用達QAサイトのトップ回答者様が書くバッチがgoto :EOF 多用で頭痛い
>>850 何か問題が?
goto :endとかより遥かにいいと思うが
自分だと大抵 {メインルーチン} goto :EOF :sub1 {サブルーチン12} exit /b :sub2 {サブルーチン} exit /b と書くことが多い。 トップ回答者様は {メインルーチン} goto :EOF :sub1 {サブルーチン} goto :EOF sub2 {サブルーチン} goto :EOF と回答されている。サブルーチンの下のはgoto は不要だし慣れない。
戻り値なけりゃどっちでもいい様な気がするが 逆に exit を避けてる人もいるよ
gotoは見通しが悪くなるから、極力使わないようにしてる 他の主流の言語だと使えないものが多いから、必然的にそういう書き方に慣れてしまった
goto は使わないに越したことはない。 が、制御構文が貧弱な言語では、熟慮の上で使わざるを得ない場面で使う。 が正解。 詳しくはWikipediaで。
C言語にはMISRAとかいう規約があるが無視していい。 あれは組み込み分野だけの特殊なものだと思っていい。 大抵の人間は、「これは思考からはぶいていい」という書き方の方が読みやすい。 だから、「これは戻すか終わらせる」と書いていっていい。 そうすれば、残ったものに集中できるだろ? まぁ、日ごろ「自分が辞めた後にこれを読まされる人間が困らないかどうか」って考えて書いてるかどうかってことだ。
あちこちでreturnするのもスパゲッティなgotoと大差がない気がするんだ テロ的というか
gotoもイディオムに従って使えば混乱しない バッチファイルだとforの方が理解不能で害悪
>>860-861 IPAの出してるMISRAの解説書のreturnは1か所にしろというルール、
あれはクソofクソのルールだと思うね。early returnこそ正義
Cとbatの書き方は全然比較にならないけど
>>861 むしろ goto の良い使い方と言われている制限が、return をまねたもの。
バッチファイルかパワーシェルでIPv4のIPアドレスのみを取得して環境変数に代入するにはどういうコマンドになりますか? 教えてください
「powershell ip address」で検索!
>>867 環境変数IPAddressに192を含んだIPアドレスを代入するサンプル(PowerShell 2.0併用)
set CMD=powershell -command "& {ipconfig |? {$_ -match 'IP.*: 192\.'}|% {$_ -replace '.*: (\d+\.\d+\.\d+\.\d+)','$1'}}"
for /f "usebackq delims=" %%a in (`%CMD%`) do set IPAddress=%%a
echo %IPAddress%
PowerShell部分はipconfigの結果から正規表現でIPと: 192という文字を含む行を抽出
抽出した行のIPアドレス部分のみ正規表現の置換で抽出といった感じ
PowerShell3.0以降だともうちょっと素直に書ける感じだけど
アダプタが1つだけならこんなでいいんじゃね? setlocal enabledelayedexpansion for /f "tokens=2 delims=:" %%a in ('ipconfig ^|find "IPv4"') do set IPADRESS=%%a set IPADRESS=%IPADRESS:~1% echo %IPADRESS%
この処理作るのにバッチとパワーシェル組み合わせないとできないんですか? ip取得するだけでも結構大変なのですね
と思ったらバッチだけでもできそうなんですね、アダプターは一つです ちょっと色々教えてもらったのでテストしてみます!
遅延変数展開の呪文要らなかったわ、1行目削っていいよ
遅延環境数ってforとifの()で使用するときだけ必要なんでしたっけ?
だいたいその理解でおk forやifの()内のスクリプトブロックが複数処理で変数代入とその参照のペアがある場合に使う 1処理だけとか、代入だけとかなら不要
無限ループの原因は何か SET A=1073741824 FOR /L %%B IN (-%A%,%A%,%A%) DO ECHO %%B
set /a A=1073741824 1073741824 set /a B=A+A -2147483648 となるからね、32bitINTの範囲が-2147483648~-2147483647 2進表記の最上位bitが1が立ってしまったらマイナス値
試してみるとfor /l 文ではステップ値が1073741824以上の場合必ずバグったループになるね、まあ仕方ないのかも
内部的にどんな計算してるか気になるところです B は -1073741824,0,1073741824 なので 普通に考えると32ビットのオーバーフローはしてない筈
ああ、分かった 4ループめでオーバーフローするのか 3ループめで最終値に等しいと抜けるんじゃ無いわけか
バッチファイルのif文でパワーシェルのif -Orみたいな処理できますか?
IFの条件は2個の値を比較するだけ 複雑なOR,AND,XORとかあるんなら計算して結果を変数に入れる それをIFの条件で使う
あると便利なミニミニバッチ DOS窓に今の時間を表示しておく m.bat @echo off setlocal set x=%date:~5% %time:~0,5% %* title=%x% exit /B 0 画面クリア c.bat @echo off cls exit /B 0 クリップボードクリア cc.bat @echo off echo.|clip echo clip clear exit /B 0
時刻表示ならプロンプト変えたら?
clsは
>>884 クリップボード履歴管理系のアプリ使ってる人には無用?
>>884 一文字でいいので、お菓子を食べながらでもできる、大差
copyコマンドがおかしい copy x+y z とするとzに改行追加されている copy /B x+y z だと問題なしだが??
改行じゃなくて 0x1A の 1byte なら付加されるが echo test> a dir a copy a /b + nul /a dir a サイズが 1byte 増える
>>891 以前から知られていたのですね
そのサイトはウィルス注意報が出たので見ませんでしたが
テキストファイルのEOF(0x1A)は前世紀の遺物 昔のテキストエディタはファイルの末尾にEOF(0x1A)を付加していた。 仕様が古すぎて今じゃCOPYのヘルプを見ても、詳細が分からん状態 copy でファイルを連結する時は /a がデフォルト ちなみに copy /a はEOF(0x1A)を付加するだけじゃないぞ ファイルの途中に0x1Aが有ったらそれ以降が無くなってしまう怖い仕様 あと、echo xxx >> とかでテキストを追加したら末尾の0x1Aは勝手に削除される
>>30 >>31 ずいぶん昔の質問で悪いんだが
これって全ての引数を意味する「%*」に起動時のコマンドラインは含まれないってこと?
chcp 65001入ってるスクリプトをUTF-8で保存して動かしてみたらエスケープ処理が酷い・・・
>>895 そうです
バッチはいろいろ癖があるので、そんなものだと思うしかないです
別件
echo %*
shift
echo %*
rem %* はshiftされない
echo %__APPDIR__% C:\Windows\SysWOW64\ これが出る時32ビットのコマンドプロンプトらしいんですが 64ビットのコマンドプロンプトと何か違うんでしょうか
reg query "HKU\.DEFAULT\Control Panel\International" 表示された最後の行に HKEY_USERS\.DEFAULT\Control Panel\International\・・・・・・ これは何だろうとレジストリエディタで見ると謎の文字で地球が3つ。 しかしメモ帳で表示出来る文字が コンソール画面で表示出来ないのはダメだね
メモ帳「俺はだいぶ前からユニコード対応済みだから表示はするさ、ANSI(CP932)で保存はできなくてもなー」
DIRコマンドでもユニコード対応してるよね。ちゃんと表示される。 でもこの地球文字はDIRコマンドでも表示されないようだ フォントの問題かねえ
フォント問題だね、 メモ帳とかレジストリエディタはフォントリンクで表示用フォントが持ってないコードも他のフォントにあればそれで代用表示するから
そんな文字(絵文字?)があるのか。 初めて見て、びっくり。(; ̄Д ̄)
for /f %a in ('dir /b') do echo %~za,%~ta なんてことできたんだねえ、 dir /bは他の属性情報を削いでるからできないと思い込んでた
>>908 dirで取得した情報使うわけじゃないから
カレントにxxx.txtとかのファイルがあれば
for /f %a in ("xxx.txt") do echo %~za
とかできるよ
dpnxfだったら単にファイル名にカレントのパスを付けるだけだからチグハグでも出来ちゃうんだぜ aaa.txtっていうファイルがカレントに存在してなくても構わないってことだ pushd d:\xxx\yyy for /f %a in ("aaa.txt") do echo %~fa ってやれば、d:\xxx\yyy\aaa.txtっていう架空のファイルのフルパス名を表示してくれる
>>905 俺のブラウザが古いのかうまく表示されなかったけど、これか。
質問です。 データが以下のように入っているcsvファイルを 指定された削除対象のファイル名の行を削除したいです。 削除対象は別ファイルに一覧としてあります。 イメージとしては以下のようにしたいです。 bass.csv ================================ ファイル名,日付,時間 AAA,20111001,1300 AAB,20171001,1300 AAC,20171031,1300 AAD,20171031,1300 ================================ delete.txt ================================ AAB AAD ================================ output.csv ================================ ファイル名,日付,時間 AAA,20111001,1300 AAC,20171031,1300 ================================ OSはWindows7 コマンド(batでもOK)でoutput.csvのような形にしたいのですが 上手くいかず、findstr /V で1行だけ試しにやってみたら理想と近い形になったのですが、 削除対象が複数になると上手くいきませんでした。
? findstr /v "AAA AAD" bass.csv>output.csv で行くはずだがだめだった? これが行ければ除外パターンを作るfor /f文を前段に作るだけで終わると思うが
行けるじゃん…そういえばfindstrは/gオプションあるから、for文も要らんね findstr /v /g:delete.txt bass.csv>output.txt なおfindstrの複数検索パターン指定は和文だと失敗する。 英数字の検索なら問題なし
よくわからんが FINDSTR /B にして検索文字列のあとに , を付ければいいんじゃね
行頭以外にAAAやAADが記述されており、それは出力したいなら /B は合った方がいい
無いとファイル名の部分一致するかも 拡張子あるなら末尾の , は要らんかも 和文ダメなんだ知らんかった
>>912 和文無ければ不要のバッチ
@echo off & setlocal & set /a n=0
for /f "delims=" %%i in (delete.txt) do set "s=%%i" & call :x
if %n%==0 (goto :eof ) else set /a n-=1
echo ファイル名,日付,時間> output.csv
for /f "skip=1 delims=" %%i in (bass.csv) do set "s=%%i" & call :y
goto :eof
:x
set "d%n%=%s%" & set /a n+=1 & goto :eof
:y
for /f "delims=," %%j in ("%s%") do set "s1=%%j" & call :z
goto :eof
:z
setlocal enabledelayedexpansion
for /L %%k in (0,1,%n%) do if /i "!s1!"=="!d%%k!" goto :eof
echo !s!>> output.csv
>>920 3行目訂正
if %n%==0 (copy bass.csv output.csv & goto :eof ) else set /a n-=1
おいらが書くならこう @echo off setlocal enabledelayedexpansion for /f %%a in (delete.txt) do set list=!list!,%%a set list=%list:,= % for /f "delims=" %%b in (bass.csv) do ( set "line=%%b" set /a flg=0 for %%b in (%list%) do ( echo !line!|findstr /b /v "%%b">nul 2>&1 set /a flg +=!errorlevel! ) rem echo !cnt! if !flg! equ 0 echo !line!>>output.txt ) pause
>>899 x64だと
C:\Windows\System32\
x64だと64bitで書いたアプリもあるのでフォルダで区別
ここらへんwindows自体が手品のようなことをしていていわば巨大ウィルスソフト化
x64はintelの失敗作、性能を優先しすぎて使い勝手が大幅に悪くなった
CSVのフィルタ処理をバッチでやろうとは思わないけど参考になった
すまん、
>>922 の内側のfor分の %%変数は%%cの方がよかった。
ローカル変数的な振る舞いで動作上は問題ないけど
先輩方、お知恵ありがとうございます。 情報の後出しとなってしまって大変申し訳ありません。 ファイル名には枝番がふられているものがあり、 delete.txtに記載されている「AAB」を削除指定すると枝番01,02の記載迄消えてしまう為 ファイル名と完全一致の行のみを削除するにはどのようにすれば良いかお知恵をお借りしたかった次第です。 bass.csv ================================ ファイル名,日付,時間 AAA,20111001,1300 AAB,20171001,1300 AAC,20171031,1300 AAD,20171031,1300 AAB01,20111001,1300 AAB02,20111001,1300 ================================ delete.txt ================================ AAB AAD ================================ output.csv ================================ ファイル名,日付,時間 AAA,20111001,1300 AAC,20171031,1300 AAB01,20111001,1300 AAB02,20111001,1300 ================================
delete.txtにカンマ加えて書けばいいんでないの? AAB, AAD,
>>926 >>920 でOK
>>922 delete.txtの中の
テキストに半角スペースや ! 文字があると誤動作
>>926 もし
>>920 を使うなら
>>921 で訂正してください
>>923 質問は64bitならどういう値になるって質問ではなくて、
32bitの場合と64bitの場合とで機能・動作的に何が違うの?
って意味だと思うけど
>>928 半角スペースはケアレス、!は全く気にしていなかった。勉強になった。有難う
Ruby で作った require 'csv' delete_files = { } # 削除するファイル名を入れる、ハッシュ text = <<TEXT AAB AAD TEXT # 改行区切りで、改行を除去してから、ハッシュに入れる text.each_line do | line | # 各行 line.chomp! # 末尾の改行を削除する next if line.empty? # 空行は処理しない delete_files[ line ] = true end # コロン区切りのCSV 入力ファイルを、1行ずつ処理する CSV.foreach( "bass.csv" ) do |row| # 削除対象ファイルの行は、出力しない puts row.join( "," ) unless delete_files.has_key? row[ 0 ] end
>>923 レスありがとうございます。
OSはwin10x64で実行されたcmdの呼び出し元は
C:\Program Files (x86)にあるアプリケーションです
%__APPDIR__%はC:\Windows\SysWOW64\
%ComSpec%はC:\WINDOWS\system32\cmd.exe
左上にある窓のtitleは%ComSpec%と同じで、何か変です
タスクマネージャーにはコマンドプロンプト(32ビット)と出ます
OSから直接cmdを起動したら(32ビット)は出ません
OSが自分自身を騙してるのでしょうか
たぶん機能上は違いが無いと思いますが
その呼び出してるアプリが32bitアプリなのだと予想
C:\Program Files (x86)なので32ビットですね
64bitOSでの32bitアプリはエミュレーションみたいな物で、32bitアプリから64bitのdllは使えないし、その逆も出来ないようになってる。なのでcmd.comも分けてあるという理由でメモリや動作モード以外の機能差は無いのではなかろうかと
32bitアプリから見た C:\Windows\System32 の実体は C:\Windows\SysWOW64 だから、 System32にあってもSysWOW64にないコマンド(WSL関連とか)は実行できないとか、 環境変数の値がビット数に応じて違うとか、その程度の違い
試しに 64ビットでビルドしたコマンドは 普通に動作しました >echo %__APPDIR__% C:\Windows\SysWOW64\ >Hello_World.exe Hello World!
以前は確かsystem32のcmdとSysWOW64のcmdが同じだったんだ そんでもってWinSxSのcmdが違っていた 今はsystem32とSysWOW64が違うんだな WinSxSのはsystem32と同じになってる 手品の種が変った?
>>926 作ってみた。ファイル名に%がはいらない前提ですが、こんな手もあるということで勘弁願いたい。
@echo off
set t=tmp.bat
echo type bass.csv^^>%t%
for /f "delims=" %%a in ( delete.txt ) do (
echo ^| find /v "%%a,"^^>>%t%
)
echo ^>output.csv>>%t%
call %t%
del %t%
夜見た時は何をやってるのか分からなかった。 finnd /vをパイプでパターン数繰り返すわけね。
%ってファイル名に使えるんだね 半角記号でバッチの挙動に関係するのは「!」くらいしか知らなかったわ。 じゃあ変数名と同じ名前のフォルダ(例えば「%appdata%」)に cdで移動するのは無理って事?
@echo off md %%appdata%% cd %%appdata%% cd pause
>set /p a= %appdata% >cd %a% >cd D:\%appdata%
for /f 文の時の()内ってダブルコーテーションのパスつっこむとダメなのね 知らなかったわ……
>>945 %の前に%を置いてエスケープするのか
どうもありがとう
遅延展開だと論理否定の単項演算子が全く使い物にならない @echo off setlocal enabledelayedexpansion set /a a=0,b=0 set /a "a=!22+!33" echo a=!a! set /a "b=!(5^5)" echo b=!b! pause なんだこの結果は a=33 b=55 正解は a=0 b=1
>>950 XORは二重引用符で囲んでも更にエスケープの謎仕様
@echo off
set n=!
setlocal enabledelayedexpansion
set /a a=0,b=0
set /a "a=!n!22+!n!33"
echo a=!a!
set /a "b=!n!(5^^5)"
echo b=!b!
pause
a=0
b=1
標準インストールされてるという以外に長所はないよなぁ
今のWindowsなら、Powerchell?、WSH?なら、標準インストールされているが・・・・。 以前なら、REXX(PC-DOS)とか、QBASICあたり? でも、使い物になるのは・・・・。
QBASICは中身がないので別途買わないと動かないよ
>>951 !を取って
set /a "b=(5^^5)"
では
オペランドがありません。
0
って出るのは何故?
>>956 謎ですねえ
>cmd /v:on
>set n=!
>set /a "a=!n!(123^456)"
0
>set /a "a=!n!(123^^456)"
0
>set /a "a=!n!(123^^^456)"
0
>set /a "a=!n!(123^^^^456)"
オペランドがありません。
>set /a "a=(123^456)"
435
>set /a "a=(123^^456)"
オペランドがありません。
遅延変数が無くても NOT演算がある時に再エスケープ(^^)が必要みたいね >cmd /v:on >set /a "a=!(123^123)" 0 >set /a "a=!(123^^123)" 1 >set /a "a=(123^123)" 0 >set /a "a=(123^456)" 435 > 一番上の式は !(123123) で 0 になってると思う
遅延無しの環境では二重引用符だけでエスケープは要らないようだ >cmd /v:off >set /a "a=!(123^123)" 1 >
遅延モードでは式の中に ! 文字があると展開の処理が違うんだろう。 だから ^ 文字の扱いも変化する。
@ECHO OFF
REM 単項演算子 ! を使用しないNOT演算
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /L %%I IN (-3,1,3) DO (
SET /A A=%%I
SET /A "B=~(A|-A)
>>31 &1"
ECHO A=!A! , NOT A=!B!
)
PAUSE
IF使えば簡単だけど
%~nx0 が変だ >dir /b test.bat >type test.bat @echo file="%~nx0" >test file="test.bat" >"test" file="test" >
どうも先頭の引用符が怪しい >.\"test" file="test.bat" >test" file="test.bat" >"test file="test" >
>t"E"s"T" file="test.bat" >"t"E"s"T" file="t"E"s"T" 先頭が引用符だと %~nx0 は入力丸写しの 拡張子無視のバカ仕様らしい
7z の個別連続圧縮のやり方を教えてください。 あまり詳しくなくてネットを見て見よう見まねで作ったので自分でもよく分かってません。 @echo off set exe7z="C:\Program Files\7-Zip\7z.exe" :start if "%~1"=="" exit /b %exe7z% a -r -mmt=on -mx=9 -ssw -txz "%~dpnx1.7z" "%~1" shift goto start このままだと作成された 7z のファイル名に元ファイルの拡張子が付いてしまいます。 dpn1 だとファイル名の拡張子は消えるけど、作成された 7z の中のファイルは拡張子が消えた状態になってしまいます。 ファイル名から元の拡張子を消し、中のファイルは拡張子を残したままってどこを変えればよいのでしょうか?
単に7zipのcliコマンドオプションの使い方で、バッチと関係ないなあ...
-txz だと書庫のヘッダににファイル名の情報は無い 書庫名を変えて開くと中のファイル名も同じく変わるだけ 中身は同じ
要するにxzファイルフォーマットの限界だな。ファイル名を保持する機能が無い
xzじゃないとダメなの? zipやrarや7zにしちゃダメなの?
>>968 が何をしたいのか分からん。
-txz なのに拡張子が .7z になってる。
なぜ .xz にしないのか。
ところで、結局、DOSでの圧縮はどの形式がおすすめ?
lzhは脆弱性があるから使うべきではない zip一択 DOSで使えるzipアプリがあるかどうかは知らん
>>981 > lzhは脆弱性があるから使うべきではない
脆弱性は対策されてるよ
使用しない方がいいと言うのはlzhの脆弱性じゃなくてアンチウイルスソフトが対応しないから
そもそもアンチウィルスソフトに対応してもらえないってのが脆弱性でしょ。 事実上公式最新版のUNLHA.DLLはソース非公開で ソース公開してる古いDOS版はヘッダ構造体がサイズ固定で静的に確保されてるから、 例えばDOSでは考慮しなくて良かった数千文字の 長いファイル名があるとバッファオーバーランを引き起こす。 アンチウィルスソフトによってはDOS版のソースを使ってるので バッファオーバーランを発生させるようなヘッダを不正扱いして 該当書庫のそれ以降の圧縮ファイルの検査をスルーするものがあるが、 そのような検査されない圧縮ファイルであっても事実上公式のUNLHA.DLLでは解凍できてしまう。 検査はされないが解凍できてしまうようなファイルにウィルスしこまれたら大変ってのが「脆弱性」なわけ。 アンチウィルスソフトが対応してくれないなら脆弱性は対策されてるとは言えないっしょ。 対処法は誰かが移植性の高いソースコードを書いて公開するぐらいしかないよーな。
>>983 どっちもねーよアホンダラ。
LHA は日本独自の圧縮アルゴリズム&zipに追い越された。
いわゆるガラパゴス技術。いらん。
数年前まで役所が .lzh とかで何かしら添付ファイル送ってくることがあって文句付けようかと思ったことがある。
>>983 今時16bit環境なんかで使ってる奴いないだろ
unlha32.dllは脆弱性の対策されてるから言いがかりレベル
純粋なDOS(16bit)を使っててウィルスが怖いなんて思う人いるのか
>>987 いやだからDOSを狙ったウィルスなんかが今時流通してるって思うのかってことさ
>>985 unlha32.dllが対策したのはバッファーオーバーランそのものについてだけ、ね。
>>983 のは、同じ書庫データなのにソフトによって取り扱い方に違いができてしまった事が原因で、
言わば仕様とかlzhのエコシステム全体の不具合だから
unlha32.dllだけ対策しました、アンチウイルスソフトが対策しねーのが悪いって喚いてもしょうがないのよ。
>>989 馬鹿なの?
そんなのlhzに限らずどんな書庫ファイルでも同じだろ
単にアンチウイルスソフトが対応しなかっだけの話
まあグローバルに展開してるマカフィーやシマンテックから見たら極東でちょっと流行ってただけのファイルフォーマットにいちいち対応してられるかよって思うのも無理はないわな
>>990 いや、lzhのヘッダは安全性そっちのけで拡張性と互換性を優先した結果、
論理的な最大ヘッダサイズが4ギガバイト(要するに制限がない)とか酷い事になってるからねぇ……
例えば最大で64キロバイト程度のzipなんかと同等に並べるのはちょっと無理じゃねーかと。
>>991 それの何が問題なんだ?
まさか4GBのメモーがないとヘッダーが読めないとか思ってるのか? w
>>992 だからウィルス対策ソフトが対応してないって話だろ
何回ループすれば理解できるんだよ w
>>993 おいおい……
64キロバイトを一括でメモリに読み込んで処理すんのと
4ギガバイトを逐次読み込んで処理しなきゃいけないのとでは
実装の難易度もコストも全然違うんだけど……
初心者でもわかりやすいところで言えば
64キロバイトの方はメモリが潤沢にあれば静的なメモリ確保でもいいけど
4ギガバイトの方は普通は動的なメモリ確保が必須になるし。
>>995 で、何が問題なの?
自分には実装できねーから糞だって話か? w
そもそも動的メモリー確保が難しいとかどんだけレベル低いんだよ w
と言う事でバカの頭に脆弱性があっただけ 終わり w
このスレッドは1000を超えました。 新しいスレッドを立ててください。 life time: 619日 22時間 49分 43秒
5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/ ▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php
read.cgi ver 07.7.25 2025/07/21 Walang Kapalit ★ | Donguri System Team 5ちゃんねる
lud20250802095647ncaこのスレへの固定リンク: http://5chb.net/r/tech/1489207631/ ヒント: 5chスレのurlに http ://xxxx.5chb .net/xxxx のようにb を入れるだけでここでスレ保存、閲覧できます。 TOPへ TOPへ
全掲示板一覧 この掲示板へ 人気スレ |
Youtube 動画
>50
>100
>200
>300
>500
>1000枚
新着画像 ↓「【.cmd】 バッチファイルスクリプト %12 【.bat】©2ch.net ->画像>4枚 」 を見た人も見ています:・今だからこそ2ch代替サービスの実装を考えるスレ ・JS初心者の集まるスレ ・★★Java質問・相談スレッド172★★ ・iphone6とmacbookpro(2015)ってまだ現役? ・Visual Studio 2019 Part2 ・Visual Studio 2019 Part5 ・Google Cloud Platformでシステム開発 ・くだすれFORTRAN(超初心者用)その7 ・VB.NET質問スレ(Part43) ・Visual Studio Code / VSCode Part4 ・日本語プログラミング言語Mind ・掲示板をapacheで外部公開したいです ・ノーコードが破綻。これからはRADツールの時代 ・java初めてみたいんだがさっぱり分からん ・Java入門・初心者質問スレ Part.7 ・大学のC++の課題手伝ってほしいんです... ・なぜ競プロ信者は遊びは遊びと割り切れないのか ・ブックマークレット【 JavaScript】 ・gPRCをおっぱじめる漢のスレ ・Windows Azure プログラミング 総合スレ2 ・俺のトリップを当ててみろ ・【HSP】Hot Soup Processor総合スレ【part 11】 ・プログラム板の姫になってもいいですか? ・Progateについて語れ ・Delphi/C++Builderが長い時を越えて再び無料に ・C/C++のソースをRustへ全力で置き換えるスレ ・統計解析R たぶんpart3くらい ・5chプログラムテスト ・【Scratch】メイクロックマン パート2 ・Visual Studio 2022 Part3 ・いじめっ子にお礼したい ・Udemyで教師やってたって全く自慢にならんよな? ・エビデンスは役に立たない。再現手順をもってこい。 ・BigQueryが非構造化データに対応。ユニケージ終焉へ ・自分中2だけど、今から言語勉強すれば稼げるかな ・【統計分析】機械学習・データマイニング33 ・オンライン投票が不可能な理由 理解できない無能IT技術者 ・各言語の記法と用語の変換スレ ・COBOL?極めてやんよ シュッシュ!! ・Android Studio 2 ・Boost C++ Libraries Sandbox ・インタープリター言語スレ。 ・★初心者以前の質問に雪崩のように答えるスレ 3★ ・くだすれDelphi(超初心者用)その58【Embarcadero】 ・文字コードの種類は何故複数あるのでしょうか? ・【分散型バージョン管理】 Mercurial 2【hg】 ・ビッグデータを活用しても新しいことはわからない ・アプレットとは何だったのか? ・Android開発質問スレ Part2 ・Reactでチャット掲示板を作っていくスレ ・Git 19 ・C#, C♯, C#相談室 Part96 ・C# vs Java どっちが好き? その5 ・Rust vs Go ・【マウスだけで】Scratch【プログラミング】その1 ・プログラム板へのID導入の投票実施中 月曜0:00まで ・プログラミングのお題スレ Part21 ・intel xdk HTML5 アプリケーション 無償のエミュ ・C# vs Java どっちが好き? その3 ・WPF(.NET, WinUI) GUIプログラミング Part26 ・5chみたいな掲示板を立てたい! ・React と React Native のスレ ・C/C++の宿題片付けます 170代目 ・【統計分析】機械学習・データマイニング27 ・松尾豊さん以外に人工知能で有名な日本人研究者
20:56:47 up 106 days, 21:55, 0 users, load average: 34.45, 53.53, 59.53
in 1.1598229408264 sec
@0.059905052185059@0b7 on 080209