放浪猫

主にガジェットとかの雑記

Windows の bat あれこれ

記憶喪失になったときのための備忘録・Windows のbat編です。

適宜更新されます。たぶん下に行くほどめんどくさい処理です。

 

実行ファイルが置かれている場所へ移動します

cd /d %~dp0 

 

%の意味

(例) hoge.bat aaa bbb

%0:D:\foo\bar\hoge.bat

%1:第1引数aaa

%2:第2引数 bbb

 

%~d0  :ドライブ文字のみ
%~p0  :パス名のみ
%~n0  :ファイル名のみ
%~x0  :ファイル拡張子のみ
%~dp0  :ドライブ文字+パス
%~nx0  :ファイル名+拡張子

%~dp0 :ドライブ文字+パス
%~nxI0 :ファイル名+拡張子
%~fs0  :完全パス+短い名前

 

標準出力・標準エラー出力のリダイレクト

コマンド > ファイルパス : 標準出力をファイルへ上書き出力

コマンド >> ファイルパス : 標準出力をファイルへ追記出力

コマンド 2> ファイルパス : 標準エラー出力をファイルへ上書き出力

コマンド 2>> ファイルパス : 標準エラー出力をファイルへ追記出力

コマンド > ファイルパス 2>&1 : 標準出力と標準エラー出力をファイルへ上書き出力

コマンド >> ファイルパス 2>&1 : 標準出力と標準エラー出力をファイルへ追記出力

 

コマンドを標準出力しない

@echo off

 

コメントアウト

rem

 

日時を表示

echo %DATE%:%TIME%

→ 2021/07/08:15:32:26.64

 

for /f "usebackq" %t in (`echo %TIME: =0%`) do @set TIMEZERO=%t & echo %DATE:~0,4%%DATE:~5,2%%DATE:~8,2%_%TIMEZERO:~0,2%%TIMEZERO:~3,2%

→ 20210708_0905

解説:%TIME%は1桁時間だと空白が入るため0埋めして、一旦%TIMEZERO%に格納し、表示された文字の文字数で切り出している。文字数の切り出しは他言語のOS環境によって07/08/2021とかになるため日本語環境のみで使用してね。他言語ならpowershell使って。

 

ユーザに入力を求める

set /p ANSWER="よろしいですか (y/n)?"
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={yes} (goto :yes)

echo キャンセルしました。

pause
exit

rem ---------------------------

:yes

echo 処理をします。

(何か処理)

pause

exit

IPアドレスからコンピュータ名を取得する

nbtstat -a 192.168.1.1

※192.168.1.1のコンピュータ名を知りたい場合

同一ネットワーク上で相手が存在するかを確認する

arp -a

MACアドレスが出る

ネットワークの接続状態を確認する

netstat -a

実行ファイルのパス (末尾に'\'あり)

set filepath=%~dp0 

echo %filepath%

 

実行ファイルのパス (末尾の'\'なし)

パターン1 移動して末尾取るパターン

pushd %~dp0
set filepath=%CD%
popd

echo %filepath%

パターン2 末尾の1文字を削り取るパターン

set tmppath=%~dp0

set filepath=%tmp:~0,-1%

echo %filepath%

 

Logフォルダがなかったら作る

 if not exist Log\ mkdir Log\ 

 

5秒経ったらタイムアウトして次の処理へ

timeout /t 5

 

実行引数がない時はエラーにする

if "%~1"=="" goto :error

 

CSVファイルを1行ずつ読み込む(複数ファイル対応版)

for %%a in ( *.csv ) do (
    for /f "eol=; tokens=1-3 delims=," %%i in ( %%a ) do (

        echo csvfile : %%a 
        echo column1: %%i column2: %%j column3: %%k

    )
)

 

robocopy処理

robocopy %from_path% %to_path% %file_name% /s /e /r:1 /w:5 /fp /np /njh /tee /LOG+:%file_name%.log

if errorlevel 8 echo Copy FAILED. & goto end

rem ※Ctrl+Cなど割り込みで死ぬときはエラー値が0未満の値になる。

よく使うオプション

  • /s サブフォルダ含める
  • /e 空フォルダ含める
  • /r:1 /w:5 リトライ1回、Wait5秒
  • /move ファイルとディレクトリを移動 (コピー後にコピー元から削除)
  • /sj /sl ジャンクションやシンボリックリンクを作る(リンク先を追跡コピーしない)
  • /fp フルパスで表示する
  • /np コピー完了率を表示しない
  • /njh /njs 忍者ヘッダ、忍者Summary(大嘘)。ヘッダやサマリを表示しない。
  • /tee /LOG+:Logfile.txt 標準出力しながらログ追記出力する(bashとかのtee)
  • /xd フォルダを除外する

 

powershell併用)同階層の.txtを読み込んで行をソートして重複行削除してshift-jisでoutputフォルダ下に出力する

if not exist output\ mkdir output\

for %%a in ( *.txt ) do (
    powershell -Command "Get-Content -Path %%a | sort -Unique | Out-File .\output\%%a -Encoding default"
)

 

powershellスクリプトなんだけどダブルクリック実行できるようにbatファイルに擬態するための最初のワンライナー

 @setlocal enabledelayedexpansion&set a=%*&(if defined a set a=!a:"=\"!&set a=!a:'=''!)&powershell/c $i=$input;iex ('$i^|^&{$PSCommandPath=\"%~f0\";$PSScriptRoot=\"%~dp0";#'+(${%~f0}^|Out-String)+'} '+('!a!'-replace'[$(),;@`{}]','`$0'))&exit/b

# ----------------------------------
# ここから PowerShell Script
# ----------------------------------

hogehoge

 

 

任意の文字列に特定の文字列が含まれるか検索

echo %TEXT% | find "AAA"
if errorlevel 1 goto :Error

 

圧縮ファイルの展開

.7z形式の場合(7zipを要ダウンロード)

7za.exe x aaa.7z -oC:\hoge\ -y

.zip形式の場合(powershellコマンドを使用)

powershell Expand-Archive -Path aaa.zip -DestinationPath C:\Users\aaa

 

レジストリの値を参照する(例:OneDrive無効化グループポリシーの設定状態を参照する)

reg query HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive\ /v DisableFileSyncNGSC

 

batからpowershell経由(Unrestrictedに一時的に昇格)して管理者権限でコマンドを実行する。(例:レジストリを操作してOneDrive無効化グループポリシー設定値を1から0に変更する)

@powershell -NoProfile -ExecutionPolicy Unrestricted -command start-process 'cmd.exe' '/c reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive\ /v DisableFileSyncNGSC /t REG_DWORD /d 0 /f' -Verb runas -Wait

 

powershel経由で.exeを実行する(例:OneDriveを起動する)

@powershell -NoProfile -ExecutionPolicy Unrestricted -command "Start-Process %USERPROFILE%\AppData\Local\Microsoft\OneDrive\OneDrive.exe"

 

ジャンクションを作成する

mklink /J %LogPath% %JunctionPath%

 

サービスを再起動する(例:ICS「SharedAccess」の再起動)

net stop SharedAccess

net start SharedAccess

 

 

新規ローカルユーザを作成する(一般ユーザ)

net user ユーザ名 パスワード /add

補足:

  • net user → 現在のユーザ一覧参照
  • net user ユーザ名 /random →ランダムなパスワード生成

 

一般ユーザを管理者グループに所属させる

net localgroup administrators ユーザ名 /add

 

コマンドの結果を変数に格納する

for /f "tokens=3 usebackq" %%i in (`find /v /c "" hoge.txt`) do SET RESULT=%%i

補足:usebackq

  • for /f "usebackq" in (`dir`) → 実行コマンドのdirとして解釈される
  • for /f "usebackq" in ('dir') → dirという文字列として解釈される
  • for /f "usebackq" in ("dir") → dirというファイル名として解釈される

ダミーファイルを作成する

空ファイル作成

type nul > dummy.txt

 

容量を指定してダミーファイルを作成(1GBの例)

fsutil file createnew dummy.dat 1073741824

 

Powershell経由で容量を指定してダミーファイルを作成(1GBの例)

@powershell -NoProfile -ExecutionPolicy Unrestricted -command "fsutil file createnew hoge.dat (1GB)"

 

カレント以下にある要素数0の空フォルダに .gitkeepファイルを作成する 。

@echo off
for /d /r %%d in (*) do (
    for /f "usebackq" %%c in (`dir %%d /b/s ^| find /v /c ""`) do (
        if %%c==0 echo created : %%d\.gitkeep && type nul > %%d\.gitkeep
    )
)