【.cmd】 バッチファイルスクリプト %12 【.bat】©2ch.net
レス数が1000を超えています。これ以上書き込みはできません。
ファイル圧縮バッチを
hta の画面にドロップするだけで実行するやつ作った
https://medaka.5ch.net/test/read.cgi/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を付ければいいんだけど
それだとファイル終端が改行になっていたら余計な空行ができる コマンドプロンプトの画面で以下の<コマンド@>を入力すると現在の年月日時分秒が表示されるのですが
これを変数に入れるにはどうすれば良いのでしょうか?
以下の<コマンドA>ではうまく入りませんでした・・・
<コマンド@>
powershell -command "date -f yyyyMMddHHmmss"
<コマンドA>
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板のスレに書いてしまったので詳細はそちらを参照して頂きたいのですが
https://mevius.5ch.net/test/read.cgi/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
だと問題なしだが?? >>890これね
ttp://shigechi-64.hatenablog.com/entry/20090717/1247798200 改行じゃなくて 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っていう架空のファイルのフルパス名を表示してくれる 質問です。
データが以下のように入っている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 レス数が1000を超えています。これ以上書き込みはできません。