ハムスターに飼われる院生のブログ

自分用メモが中心のブログです。

cpuの空きを確認してから処理を行うbatファイル

test.exe がコマンドライン引数 1 2 3 4 5 を取るとする。
この実行ファイルを最大で100回繰り返したいときに、
cpuの空きを確認して空きがあれば実行、空きがなければ600秒待機するバッチファイルを作成した。
今回はcpuが小数点切り捨て70%以下の使用率で実行とした。
cpuの使用率を確認する部分は64bit用のものなので

typeperf -sc 1  -si 1 "\processor(_Total)\%% Processor Time" | find ":" >cpu.csv

だが、32bitの場合は

typeperf -sc 1  -si 1 "\processor(_Total)\% Processor Time" | find ":" >cpu.csv

と変更する必要がある。

なお、test.exeのコマンドライン引数は文字列として扱っているため、
実際は小数を入れることも可能。
このように実行する。

testbat.bat test.exe 100 1 2 3 4 5

呼び出し先のtestbat.batは以下の通り。

@echo off
@setlocal enabledelayedexpansion

set exefile=%1
set /a loop_max=%2
set arg1=%3
set arg2=%4
set arg3=%5
set arg4=%6
set arg5=%7
set /a counter=1
for /l %%i in (0,1,1000000) do (
	call :Check_Termination
	typeperf -sc 1  -si 1 "\processor(_Total)\%% Processor Time" | find ":" >cpu.csv
	powershell sleep 1
	call :Check_CPU
	call :RunCalc
)
pause
exit /b


:Check_Termination
	if %counter% gtr %loop_max% (
		exit
	) else (
	)
	exit /b

:Check_CPU
	for /f "tokens=1-5 delims=," %%a in (cpu.csv) do (
		set v=%%~b
	)
	call :GetINT
	call :CheckVacancy
	exit /b
	
:RunCalc
	rem echo vacancy=%vacancy%
	if %vacancy%==1 (
			set /a counter=counter+1
			rem echo %counter%
			echo 計算%counter%を実行中
			start	%exefile%	%counter%	%arg1%	%arg2%	%arg3%	%arg4%	%arg5%	>	output%counter%.txt
		) else (
			echo cpuの空きに余裕がないので計算実行を待機しています
			powershell sleep 600
		)
	exit /b

:GetINT
	for /f "tokens=1* delims=." %%a in ("!v!") do (
		set /a cpu=%%~a
	)
	exit /b

:CheckVacancy
	echo cpu=%cpu% %%の使用率
 	if %cpu% lss 70 (
 		set /a vacancy=1
 	) else (
 		set /a vacancy=0
 	)
	exit /b

:fin
exit /b

cpuの使用率を一度cpu.csvに書き出している。

バッチファイルのみを他のフォルダに移動させる

任意のバッチファイルを実行後に、
バッチファイルを作業用のディレクトリに置きっぱなしにしておくと
意図せずクリックして作業時間をロスすることがあった。
これを防ぐため、実行するバッチファイルの末尾に以下の文を加えた。

mkdir batfiles
move *.bat .\batfiles

batfilesというフォルダを作成し、作業場所のbatファイル全てを移動させることができる。

一行ずつ読み込んだ内容を数値に変換する

長さの違うデータが複数列記述されているファイルをRで処理する。
今回は例として3行読み込む。

filename<-"text.txt"
f<-file(filename,"r")
for(i in 1:3){
   a<-readLines(con=f,1)  #一行ずつ読み込み
   a<-strsplit(a , ",")     #カンマ区切り
   a<-unlist(a)                        #リスト形式を解除
   a<-as.numeric(a)               #numericに変換
   print(a)#各行に行う処理(今回は画面出力)
}

特定の箇所のみ出力するrubyプログラム

一つのファイルに複数の情報を書き込んでいる際に、以下のように取り出したい内容が区切られているとする。

<HOGE>
取り出したい内容
</endHOGE>

この取り出したい内容を拾い出すプログラムを作成した。
ファイル名は入力で与えている。

file=open(ARGV[0])
lines=file.read().split("\n")
export=false
lines.each do |line|
	if line =~/<HOGE>/
		export=true
	end
	if line =~/<endHOGE>/
		export=false
	end
	if export then
		puts(line)
	end
end
file.close

指定した文字列以降を出力するrubyプログラム

指定した文字列以降を出力するrubyプログラムを作成した。

a,b,c,d,
-----------------------------
A,B,C,D,

このようなファイルがあったとして、
”-----------------------------”を含めてそれ以降を出力する。
読み込む対象のファイル名は引数で与える。

file=open(ARGV[0])
lines=file.read().split("\n")
export=false
lines.each do |line|
	if line =~/-----------------------------/
		export=true
	end
	if export then
		puts(line)
	end
end
file.close

vectorで指定した値を持つインデックスを複数返す

vec1の要素のうち、targetで指定した値を持つインデックスを複数返す関数を作成した。

vector<int> detectIndex(vector<double> vec1, double target) {
	vector<int> result;
	for (auto itr = vec1.begin(); itr != vec1.end(); ++itr) {
		if (*itr == target) 
			result.push_back(std::distance(vec1.begin(), itr));
	}
	return result;
}

バッチファイルでフォルダを作成してから計算実行

このようにフォルダ分けをして計算結果を書き出す場合を考える。

call test.exe >case1/condition1/output.txt
call test.exe >case1/condition2/output.txt
call test.exe >case1/condition3/output.txt

この場合、case1/condition1等のフォルダが存在しないと実行時にエラーとなる。
これを防ぐため、バッチファイル内で自動でフォルダを作成するように
以下の文をバッチファイルの冒頭に記述した。

mkdir case1
cd case1
mkdir condition1 condition2 condition3
cd ../

フォルダ数が少なければこの方法で対処することができる。