私的ITチートシート_バッチ作成レシピ(2024/04/22更新)

【PR】
※IT系の記事は当方環境での実施内容となるため実施する場合は自己責任でお願いいたします。

■Windowsバッチレシピカテゴリ

■Linuxバッチレシピカテゴリ

目次

PowerShell

Windowsのコマンドで〇月〇日(西暦いらない)を表示する

CMDで見つからなかったので、そんな時はPowerShellで。

Get-Date -Format M

もしくは

    
Get-Date -Format MM月dd日

copy-itemの上書き保存とフォルダごとコピー

※ファイルであれば基本的にデフォルト上書きだが、フォルダはそのままでは上書きされない
※UNC表記可
■ファイルコピー
copy-item コピー元ファイル コピー先ファイル
■フォルダコピー
copy-item コピー元フォルダ コピー先フォルダ -Recurse
■フォルダごと強制上書き
copy-item コピー元フォルダ コピー先フォルダ -Recurse -Force

スクリプトを実行しようとすると、このシステムではスクリプトの実行が無効になっているため・・・と出るとき

コマンドプロンプトを「管理者権限」で起動
ps1スクリプトの実行を許可する
PowerShell -ExecutionPolicy RemoteSigned sample.ps1

システム全体でps1スクリプトの実行を許可する

PowerShell Set-ExecutionPolicy RemoteSigned

Windowsバッチ

echoで空行を出力する

echo. >c:\hoge.txt

タスクスケジューラでタスクを複数回実行する

繰り返し間隔と継続時間を設定する

開始時間+継続時間内で繰り返し間隔でジョブが実行されるため、別の時間帯のジョブを別で作成することなく、1つのタスクで日の実行回数を制御可能

都度ネットワークドライブを割り当てて作業する場合

net use Z: delete
net use Z: ネットワークパス パスワード /user:サーバ名\ユーザ名
処理
net use Z: delete

というように、はじめつながっていなくても、deleteを入れておくと、万が一使用するドライブレターがすでに使われて、他とつながっていた場合に安心。

バッチの引数に絶対パスのファイルを与える時のダブルクォーテーションのあるなし

絶対パスだと長い引数になりますが、ダブルクォーテーションのあるなしどちらでも問題ありませんでした。もちろん空白は入れない方がよいでしょうが。

バッチの中からvbsを起動

バッチファイルの中で以下のように記述

cscript hoge.vbs

net use でのネットワーク接続ドライブ指定あり/なし

「/persistent:no」は次回サインイン時再接続をOFFにする。こちらの方が安心かもしれない。

ドライブ指定あり

追加
net use z: \\ホスト名\share /user:ドメインまたはコンピュータ名\username password /persistent:no
削除
net use z: /delete

ドライブ指定なし

追加
net use \\ホスト名\share /user:ドメインまたはコンピュータ名\username password /persistent:no
削除
net use \\ホスト名\share /delete

サンプルスクリプト
net use でドライブなしで接続、ファイルコピーして 切断する

net use \\hostname\share password /user:hostname\username /PERSISTENT:NO
copy \\hostname\share\hoge.csv C:\Users\Administrator\Documents\
net use \\hostname\share /delete
pause

xcopy

コマンドでディレクトリをコピーしたい時に。

INC表記は指定できないっぽいので、ドライブ割り当てしてコピー。

使用例)空サブディレクトリごと、コピー先に新規に日付付きディレクトリでリネームコピー
xcopy X:\template X:\%date:/=%_template /E /H /C /I

/E ディレクトリまたはサブディレクトリが空であってもコピーする

/H 隠しファイルやシステム・ファイルもコピーする

/C エラーが発生しても,コピーを続ける

/I 受け側がなく,複数のファイルをコピーする場合,受け側をディレクトリとしてコピーする

事前にファイルなのかディレクトリなのかを指定する

/I が無ければ受け側がファイルなのがディレクトリなのかを聞いてくるので、以下のような方法でもできます。

echo D|xcopy X:\template X:\%date:/=%_template /E /H /C
ファイルをコピーせずにサブフォルダを含めたフォルダ構造だけコピー、かつ事前に「D」指定する
echo D|xcopy /t /e X:\template X:\%date:/=%_template

copyコマンドで確認せずに上書き

copy /Y Source.txt Destination.txt

moveコマンドで確認せずに上書き

move /Y Source.txt Destination.txt

一桁時間台のtimeの結果から半角スペースを0に置換(0で穴埋め)して格納する

echo %time%
 9:50:47.86

echo %time: =0%
09:51:27.71

■変数格納
set JIKAN=%time: =0% 
echo %JIKAN% 
09:54:14.86 

さらに秒の後と「:」を取り除くには、位置指定で該当部分のみ表示するようにする
set JIKAN=%JIKAN:~0,2%%JIKAN:~3,2%%JIKAN:~6,2% 
echo %JIKAN% 
095414 

以上を定義したうえで、以下の様に実行するとログファイルとかに記載するのに便利 
echo [%date:/=%-%JIKAN%] XXXXX >> xx.log [20220902-095414] XXXXXX

日付の〇年、〇月、〇日部分のみを取得する

年部分 %date:~0,4%
月部分 %date:~5,2%
日部分 %date:~8,2%

〇月22日に22.logというログファイルを生成する時に当日生成されたファイルをtmpフォルダ配下にコピーする例

copy %date:~8,2%.log tmp

1行目が見出しとなっているカンマ区切りCSVから1列目~3列目までを別CSVファイルにエクスポートする(PowerShel)

importの方だけ-Encoding付けたら出力ファイルが文字化け。import,export両方Encoding付けておくと文字化けしなかった。

import-csv "抽出元CSVファイルパス" -Encoding default -Delimiter ","|select "見出し1","見出し2","見出し3"|export-csv "抽出後出力先CSVファイルパス" -Encoding Default

dirの出力をファイルの大きい順に並び変え

dir /o-s

「-」はソート順反転の意味

findstrで複数のtxtファイルから「A FAILED」を含む文字列を抽出する

これではだめ A or FAILEDを探してしまう

findstr "A FAILED" *.txt

「 」(空白)として見てほしければエスケープしませう。

findstr "A\ FAILED" *.txt

findstrで複数のtxtファイルから「-S」を含む文字列を抽出する

「-」はエスケープしませう。

findstr "\-S " *.txt

dirのサブフォルダ含む、パス+ファイル名のみ表示、特定の拡張子

dir /s /b *txt

バッチのSTART /WAITオプション

STARTはそのままではアプリケーションの終了を待たない(callは待つ)が、START /WAITと書くと実行したアプリケーションが終了するまで待つようになる。

START /WAIT アプリケーション
START /WAIT アプリケーション
・
・

という感じで列挙できる。

PowerShellで「tail -f」のようなことをする

get-content c:\path\to\sample.txt -wait -tail 10

必要であれば末尾に以下のように付けてEncoding
 -Encoding UTF8
Get-Content -Wait -Tail 10 -Path "ファイルへのパス"

ファイル名変数取得

ドラッグファイル(一番目の引数)格納用変数

%1

ファイル名の拡張子前までを取得

fname=%~n1

ファイル名の拡張子を取得

kakuchosi=%~x1

バッチファイルの格納先ディレクトリパスを取得

dirpath=%~dp0

上記を組み合わせて何か変換をかけたいファイルをドラッグして変換後、別名で保存したい時など
例)CRLFをLFに変換して別名保存

%dirpath%nkf.exe -0Lu %1 %dirpath%\%fname%_LF%kakuchosi%

Whereコマンドでフォルダ配下のファイルをサブフォルダも含めタイムスタンプとファイルサイズをすっきりと一覧表示する

カレントのファイルすべて

where /R . * /T 

ファルダ配下の拡張子を持つファイル

where /R フォルダ *.* /T

実行例
C:\Users\hoge>where /R Pictures * /T
124133 2022/05/18 17:42:22 C:\Users\hoge\Pictures\x206434.jpg
101943 2022/05/16 11:22:20 C:\Users\hoge\Pictures\x214691.jpg
101653 2022/05/16 11:22:04 C:\Users\hoge\Pictures\x214691.png
314441 2022/05/18 0:26:00 C:\Users\hoge\Pictures\x234390.jpg

日付変数(YYYYMMDD)

%date:/=%

日付変数日付(YYYYMM)

%date:~0,4%%date:~5,2%

今日日付(バッチ内PowerShell使用)

FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.ToString"("'yyyyMMdd'")"`) DO SET today=%a

FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.ToString"("'yyyy/MM/dd'")"`) DO SET today=%a

過去未来日付(バッチ内PowerShell使用)

YYYYMMDD形式(1日前)
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("-1")".ToString"("'yyyyMMdd'")"`) DO SET yesterday=%%a

以降、使用したい箇所で%yesterday%で使用可能

YYYYMMDD形式(1日後)
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("+1")".ToString"("'yyyyMMdd'")"`) DO SET tomorrow=%%a
YYYYMM形式(100日前)
FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.AddDays"("-100")".ToString"("'yyyyMM'")"`) DO SET yesterday=%a
YYYY/MM/DD形式(1日後)
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("+1")".ToString"("'yyyy/MM/dd'")"`) DO SET tomorrow=%%a
ちなみに「/」はファイル名やフォルダ名には使えないので
フォルダやファイル名に使えるものも欲しければ、
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("+1")".ToString"("'yyyy/MM/dd'")"`) DO SET tomorrow=%%a 
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("+1")".ToString"("'yyyyMMdd'")"`) DO SET tomorrow1=%%a 
みたいな「/」なしのものを一緒に作っておいて、使用する。

例えば「YYYY/MM/DD」があるものを抽出するが、結果のファイル名では「YYYYMMDD」をファイル名に付けるとか。
findstr "SUCCESS" c:\hoge.txt|findstr "%tomorrow%" > c:\%tomorrow1%_result.txt
DD形式で変数に格納し、利用する
9/5に実行した場合

FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.AddDays"("-1")".ToString"("'dd'")"`) DO SET yesterday1=%a
FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.AddDays"("-2")".ToString"("'dd'")"`) DO SET yesterday2=%a
FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.AddDays"("-3")".ToString"("'dd'")"`) DO SET yesterday3=%a
FOR /F "usebackq" %a IN (`powershell [DateTime]::Today.AddDays"("-10")".ToString"("'dd'")"`) DO SET yesterday4=%a

echo %yesterday1%
04
echo %yesterday2%
03
echo %yesterday3%
02
echo %yesterday4%
26

こんな感じで使う(昨日のdd.logがある時)
copy c:\hoge\%yesterday1%.log c:\hoge\hoge\


先月のYYYYMM(コマンドラインの中でPowerShellを実行)

バッチファイルの中で使う場合は「%」を2つにする。コマンドラインで直接実行は%は1つでよい。

FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddMonths"("-1")".ToString"("'yyyyMM'")"`) DO SET lastmonth=%%a


来月のYYYYMM(コマンドラインの中でPowerShellを実行)

+1で翌月、年、月を入れたフォーマットも可能 
FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddMonths"("+1")".ToString"("'yyyy年MM月'")"`) DO SET nextmonth=%%a

 

PowerShellが使えないWindowsは撲滅希望(笑)

findstr

■A or B
findstr "A B" sample.txt

■A and B
findstr "A" sample.txt|findstr "B"

■空白を含む
findstr /C:"A B" sample.txt

copyで条件に合うファイルを連結コピー

copy /b *.log 連結コピー後ファイル名

Linuxシェルスクリプト


ls -laで複数のファイルを指定する

/root/work配下に以下のようなファイルがあり、それを一度にls -la するには
abc ehg hij0 hij1 hij2 hij3 hij4 hij5 hij6 klm1 klm2

ls -la /root/work/{abc,ehg,hij[0-6],klm[12]}

とすると以下のような感じで出力されます。

-rw-r--r--. 1 root root 0 12月 29 13:52 /root/work/abc
-rw-r--r--. 1 root root 0 12月 29 13:52 /root/work/ehg
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij0
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij1
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij2
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij3
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij4
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij5
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/hij6
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/klm1
-rw-r--r--. 1 root root 0 12月 29 13:53 /root/work/klm2

{A,B,C} A or B or C のいずれかにマッチ
[0-6]0,1,2,3,4,5,6のいずれかにマッチ
[12]1,2のいずれかにマッチ

ファイルの有無を一度に確認する時に便利。

日付変数(Linux)

YYYYMMDD
date '+%Y%m%d'
YYYYMMDDHHMM
date "+%Y%m%d%H%M"
YYYY/MM/DD
date "+%Y/%m/%d"
一日前のYYYYMMDD,YYYY/MM/DD
date +%Y%m%d --date '1 day ago'
date +%Y/%m/%d --date '1 day ago'
一か月前のYYYYMM
date -d '1 month ago' +%Y%m
20日後のyyyy/mm
date --date "20 days" "+%Y/%m"

 

Teratermマクロ

Teratermマクロコマンド

https://ttssh2.osdn.jp/manual/4/ja/macro/command/index.html

getpassword パスワードファイル ユーザーネーム パスワード →パスワード取得
connect ホスト名 →ホストへ接続
strconcat 変数 '任意の文字列' →変数と'文字列’を連結して変数に格納する
pause 数字 →数字秒停止
sendln '任意のLinuxコマンド' →任意のLinuxコマンドを接続先で実行する
unlink →メニュー表示するLinuxコマンドを実行させたあとマクロを解除して、ウィンドウの制御をしなくする
wait 'word' ⇒指定した語句が返ってくるまで待つ
showtt 0 ⇒Teratermの画面を最小化する 表示が長い場合は最小化した方が圧倒的に速い
showtt 6 ⇒ログ取得中にログウィンドウ画面を隠す

ファイル送信

送信元ファイル、送信先ファイルをそれぞれ定義し、scpsendで送信

SOURFILE = 'C:\Path\to\file' (ネットワークのUNCパス「\\」でもOK)
DESTFILE = '/Path/to/File' (Linuxの配置したいファイル名の絶対パス)

scpsend SOURFILE DESTFILE

XXX.logから「AA一文字以上の繰り返し5回BB」かつOK]YYYYMMDDを抽出する

sendln 'grep "AA.....BB" /home/hoge/grep.txt |grep OK]`date +"%Y/%m/%d"`'

WinSCPスクリプト

共通

option batch on
option confirm on

open username:password@servername

cd /hoge
option transfer binary

取得処理

close

exit

スクリプトファイル内のコメント

行頭に「#」

getコマンドの除外

get -filemask=|b.* * C:\Users\hoge\Documents\winscp-test\
⇒全てのファイルを対象にするが、b.で始まるファイルは除外する
a.txt                     |           55 B |    0.0 KB/s | binary | 100%
a.log                     |            0 B |    0.0 KB/s | binary |   0%

get -filemask=|a.* *.log C:\Users\hoge\Documents\winscp-test\
⇒.logで終わるファイルを対象とし、かつa.*で始まるファイルは除外する
b.log                     |            0 B |    0.0 KB/s | binary |   0%

get -filemask="|aaaa0095*;aaaa0096" *.log C:\Users\hoge\Documents\winscp-test\
⇒aaaa0096,aaaa0097で始まるファイル名以外の.logファイルを取得する
aaaa0097.log | 0 B | 0.0 KB/s | binary | 0%

get  get -filemask="|aaaa0095*;aaaa0096*;bbbb/" * C:\Users\hoge\Documents\winscp-test\
⇒aaaa0096,aaaa0097で始まるファイル名及びbbbbディレクトリとその配下以外の.logファイルを取得する
 この場合、bbbbディレクトリ配下に合致するファイルがあったとしても取得されない
winscp> ls bbbb
-rw-rw-r-- 1 hoge hoge 0 Apr 22 11:04:49 2024 aaaa0096.log
drwxrwxr-x 3 hoge hoge 4096 Apr 22 11:05:11 2024 ..
drwxrwxr-x 2 hoge hoge 4096 Apr 22 11:04:49 2024 .
-rw-rw-r-- 1 hoge hoge 0 Apr 22 11:04:49 2024 aaaa0095.log
-rw-rw-r-- 1 hoge hoge 0 Apr 22 11:04:49 2024 aaaa0097.log

aaaa0097.log | 0 B | 0.0 KB/s | binary | 0%

getコマンドのファイル格納先にフォルダを指定する場合は最後に「\」で閉じるのを忘れずに

エラーになります。

getの-neweronlyオプションを検証する

getの-latestと-neweronlyはうまく使うと対象のファイルを効率よく取得できそうです。

サーバ上にa.txtとb.txtを作成して状態を変えながら-neweronly付きでgetしてみます。
■初回DL
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
b.txt                     |           19 B |    0.0 KB/s | binary | 100%
a.txt                     |           22 B |    0.0 KB/s | binary | 100%
⇒全てがダウンロードされる

■サーバ上のファイルに変更を加えずにgetする
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
b.txt                     |            0 B |    0.0 KB/s | binary |   0%
a.txt                     |            0 B |    0.0 KB/s | binary |   0%
⇒変更されていないのでダウンロードサイズは0Bとなっており、ダウンロードされない

■a.txtに変更を加えてgetする
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
b.txt                     |            0 B |    0.0 KB/s | binary |   0%
a.txt                     |           43 B |    0.0 KB/s | binary | 100%
⇒a.txtのみダウンロードされる

■b.txtに変更を加えてgetする
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
a.txt                     |            0 B |    0.0 KB/s | binary |   0%
b.txt                     |           55 B |    0.0 KB/s | binary | 100%
⇒b.txtのみダウンロードされる

■サーバからa.txtを削除してgetする
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
b.txt                     |            0 B |    0.0 KB/s | binary |   0%
⇒a.txtはダウンロードされないが、ローカルにダウンロードしたa.txtは残る
C:\Users\hoge>dir C:\Users\hoge\Documents\winscp-newer\
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 3E8E-224B です

 C:\Users\hoge\Documents\winscp-newer のディレクトリ

2023/12/06  15:40    <DIR>          .
2023/12/06  15:40    <DIR>          ..
2023/12/06  15:43                43 a.txt
2023/12/06  15:44                55 b.txt
               2 個のファイル                  98 バイト
               2 個のディレクトリ  63,393,484,800 バイトの空き領域

■サーバ上に新たにa.txtを作る
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
b.txt                     |            0 B |    0.0 KB/s | binary |   0%
a.txt                     |           55 B |    0.0 KB/s | binary | 100%
⇒新たにa.txtがダウンロードされ、ローカルのa.txtも更新される
C:\Users\hoge>dir C:\Users\hoge\Documents\winscp-newer\
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 3E8E-224B です

 C:\Users\hoge\Documents\winscp-newer のディレクトリ

2023/12/06  15:40    <DIR>          .
2023/12/06  15:40    <DIR>          ..
2023/12/06  15:48                55 a.txt
2023/12/06  15:44                55 b.txt
               2 個のファイル                 110 バイト
               2 個のディレクトリ  63,391,109,120 バイトの空き領域

■ローカルのb.txtを削除してgetを実行する
winscp> get * -neweronly C:\Users\hoge\Documents\winscp-newer\
b.txt | 55 B | 0.0 KB/s | binary | 100%
a.txt | 0 B | 0.0 KB/s | binary | 0%
⇒b.txtがダウンロードされる 

C:\Users\hoge>dir C:\Users\hoge\Documents\winscp-newer\
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 3E8E-224B です

 C:\Users\hoge\Documents\winscp-newer のディレクトリ

2023/12/06  17:34    <DIR>          .
2023/12/06  17:34    <DIR>          ..
2023/12/06  15:48                55 a.txt
2023/12/06  15:44                55 b.txt
               2 個のファイル                 110 バイト
               2 個のディレクトリ  63,173,144,576 バイトの空き領域

 

現在のセッションを表示

スクリプト起動時には使わないが、テストでステップで実行している時に他のセッションをcloseし忘れていないか確認する時など

session

1 hoge@server01

決め打ちのファイル名を取得

get filename c:\tmp\

昨日日付のタイムスタンプがファイル名についたファイルを取得

get *%TIMESTAMP-1D#yyyymmdd%* c:\tmp\

本日0900-1200台のタイムスタンプがファイル名についたファイルを取得

get *%TIMESTAMP#yyyymmdd%09* c:\tmp\
get *%TIMESTAMP#yyyymmdd%10* c:\tmp\
get *%TIMESTAMP#yyyymmdd%11* c:\tmp\
get *%TIMESTAMP#yyyymmdd%12* c:\tmp\

WinSCPスクリプト内の日付指定

YYYYMMDD
%TIMESTAMP#yyyymmdd%

YYYYMMDD-1
%TIMESTAMP-1D#yyyymmdd%

YYYYMM
%TIMESTAMP#yyyymm%

YYYYMMDDHH
%TIMESTAMP#yyyymmddhh%

例)ファイル名にタイムスタンプがある、実行日13時台のログファイルをすべて取得する
get hoge_%TIMESTAMP#yyyymmdd%13*.log C:\temp\

複数取得の場合はこうかな、まぁ2行にしてもよいけれど。
get hoge_%TIMESTAMP#yyyymmdd%13*.log hoge_%TIMESTAMP#yyyymmdd%14*.log C:\temp\

get command :: WinSCP


get -latestを使う

ディレクトリ配下に以下のようなファイルがあったとする
10月	23	13:36	aaa.txt
10月	23	13:35	aaa20231021.txt
10月	23	13:35	aaa20231022.txt
10月	23	13:34	aaa20231023.txt

get -latest aaa* C:\Users\hoge\work\

で取得されるファイルは条件にマッチするファイルの中で「タイムスタンプが最新のもの」となる
よってこの場合に取得されるファイルはaaa.txtとなる。

引数を与えて実行し、引数に与えたwordを含むファイルをDLする

winscp /console /script="\path\to\script.txt" /parameter hoge

get *hoge* \path\to\destfolder\

 

Posted by admin