Batch script to show multiple filenames in one call - command-line

Im trying to create a batch script to call a .exe to carry out analysis on multiple data files in a same folder. The syntax should be like:
"D:\Softwares\Analyzer.exe" [DataFile1].dat [DataFile2].dat ... [DataFileN].dat AnalysisFile.pdo"
Currently I have tried to use a FOR loop to scan each *.dat file in a specified folder. (I don't know how many data files in that folder, so I cannot type the filenames directly in the command line)
For example:
#ECHO OFF
FOR /r %%i in (*.dat) DO (
"D:\Softwares\Analyzer.exe" %%~ni.dat TestAnalysis.pdo
)
PAUSE
However, the analysis is carried out on seperate datafiles, and the .exe file will pop-up and open every time when a new .dat file is detected. Is there any way I could use *.dat or any other methods to represent [DataFile1].dat [DataFile2].dat ... [DataFileN].dat in one line seperated by a space (not a new line)?
I have also tried to use #tilte, which does not work as well. Since the .exe window keep pop-up whenever a new .dat file is detected and I have to close each of them in order to continue to next .dat file.
In general, I would like to do an automatic scan in a folder, get the names of the datafiles, and write a command line to call these .dat files in one line.
Any ideas/helps appreciated!!!

try this, remove the word echo if the output is OK:
#echo off &setlocal enabledelayedexpansion
set "line="
for %%i in (*.dat) do set "line=!line! "%%i""
echo "D:\Softwares\Analyzer.exe" %line% TestAnalysis.pdo
The code doesn't work with *dat files with exclams ! in the file name. This may be fixed if needed.

Related

Netlogo - Behavior Space

I want to run experiments using behavior space. However, the number of experiments needed is depending on the length of a list which is dynamic subject to the external data loaded. Hence , I want to do something like below which is not supported:
what is the correct way to do so? thanks
You note that you do this with a .bat or .sha file. If that's the case, here's a .bat solution. However, I'm not sure what your data looks like- in this example I just used the number of entries in a csv file to determine the number of runs needed.
So, I have a data file called 'example_data.csv' that looks like this:
1
100
1000
10000
I have an .nlogo file with an Input widget that defines a global variable called n_runs. I pulled out the xml for an BehaviorSpace experiment and saved it in a file called "experiment_base.xml"- it looks like:
<experiments>
<experiment name="experiment" repetitions="1" sequentialRunOrder="false" runMetricsEveryStep="false">
<setup>setup</setup>
<go>tick</go>
<timeLimit steps="5"/>
<metric>count turtles</metric>
<steppedValueSet variable="n_runs" first="1" step="1" last="1"/>
</experiment>
</experiments>
I have a .bat file that:
counts the number of entries in my 'example_data.csv"
reads in the 'experiment_base.xml' file and replaces the last="1" with the number read above, then writes this as a new experiment called 'mod_experiments.xml'
runs the experiment using the newly generated experiments file
This entire bat file looks like:
#echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" example_data.csv | find /C ":""
for /f %%a in ('!cmd!') do set number=%%a
powershell -Command "(gc experiment_base.xml) -replace '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"1\"/>', '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"%number%\"/>' | Set-Content mod_experiments.xml
echo "Running experiment..."
netlogo-headless.bat ^
--model dynamic_behaviorspace.nlogo ^
--setup-file mod_experiments.xml ^
--table table-output.csv
This outputs results for 4 experiments, since I had 4 values in my data file. If I modify the number of entries in the csv and rerun the .bat file, I get results for a corresponding number of runs.

Perl: Run script on multiple files in multiple directories

I have a perl script that reads a .txt and a .bam file, and creates an output called output.txt.
I have a lot of files that are all in different folders, but are only slightly different in the filename and directory path.
All of my txt files are in different subfolders called PointMutation, with the full path being
/Volumes/Lab/Data/Darwin/Patient/[Plate 1/P1H10]/PointMutation
The text(s) in the bracket is the part that changes, But the Patient subfolder contains all of my txt files.
My .bam file is located in a subfolder named DNA with a full path of
/Volumes/Lab/Data/Darwin/Patient/[Plate 1/P1H10]/SequencingData/DNA
Currently how I run this script is go on the terminal
cd /Volumes/Lab/Data/Darwin/Patient/[Plate 1/P1H10]/PointMutation
perl ~/Desktop/Scripts/Perl.pl "/Volumes/Lab/Data/Darwin/Patient/[Plate
1/P1H10]/PointMutation/txtfile.txt" "/Volumes/Lab/Data/Darwin/Patient/[Plate
1/P1H10]/SequencingData/DNA/bamfile.bam"
With only 1 or two files, that is fairly easy, but I would like to automate it once the files get much larger. Also once I run these once, I don't want to do it again, but I will get more information from the same patient, is there a way to block a folder from being read?
I would do something like:
for my $dir (glob "/Volumes/Lab/Data/Darwin/Patient/*/"){
# skip if not a directory
if (! -d $dir) {
next;
}
my $txt = "$dir/PointMutation/txtfile.txt";
my $bam = "$dir/SequencingData/DNA/bamfile.bam";
# ... you magical stuff here
}
This is assuming that all directories under /Volumes/Lab/Data/Darwin/Patient/ follow the convention.
That said, more long term/robust way of organizing analyses with lots of different files all over the place is either 1) organize all files necessary for each analysis under one directory, or 2) to create meta files (i'd use JSON/yaml) which contain the necessary file names.

How to append file's last modification date to file name on moving the file?

I have an Excel add-in for my organization that I regularly update. I have a batch file which moves the previous add-in to an "old" directory, and I want to append the file's last modified date to the file name in order to keep track of all previous versions.
Using %DATE% I can append the current date to the filename, but I want to know how I can append the date for when the file was last modified.
This is my batch file so far, using the %DATE% command.
Ren J:\40_MS\435_Milj›\Annet\Datah†ndtering\Add-ins\435_Milj›.xlam 435_Milj›_old.xlam
Move J:\40_MS\435_Milj›\Annet\Datah†ndtering\Add-ins\435_Milj›_old.xlam J:\40_MS\435_Milj›\Annet\Datah†ndtering\Add-ins\Old\
Ren J:\40_MS\435_Milj›\Annet\Datah†ndtering\Add-ins\Old\435_Milj›_old.xlam 435_Milj›_%DATE%.xlam
Any suggestions are greatly appreciated.
The suggested duplicate doesn't actually explain how to append the file date to the file name. I tried using this script:
Ren C:\Temp\435_Milj›.xlam 435_Milj›_old.xlam
Move C:\Temp\435_Milj›_old.xlam C:\Temp\Old\
for %a in (C:\Temp\Old\435_Milj›_old.xlam) do set MyFileDate=%~ta
Ren C:\Temp\Old\435_Milj›_old 435_Milj›_%MyFileDate%.xlam
But it didn't work. What am I doing wrong?

How to batch rename files to 3-digit numbers?

I apologize in advance that this question is not specific. But my goal is to take a bunch of image files, which are currently named as: 0.tif, 1.tif, 2.tif, etc... and rename them just as numbers to 000.tif, 001.tif, 002.tif, ... , 010.tif, etc...
The reason I want to do this is because I am trying to load the images into matlab and for batch processing but matlab does not order them correctly. I use the dir command as dir(*.tif) to get all the images and load them into an array of files that I can iterate over and process, but in this array element 1 is 0.tif, element 2 is 1.tif, element 3 is 10.tif, element 4 is 100.tif, and so on.
I want to keep the ordering of the elements as I process them. However, I do not care if I have to change the order of the elements BEFORE processing them (i.e. I can make it work to rename, for example, 2.tif to 10.tif if I had to) but I am looking for a way to convert the file names the way I initially described.
If there is a better way to get matlab to properly order the files when it loads them into the array using dir please let me know because that would be much easier.
Thanks!!
You can do this without having to rename the files, if you want. When you grab the files using dir, you'll have a list of files like so:
files =
'0.tif'
'1.tif'
'10.tif'
...
You can grab just the numeric part using regexp:
nums = regexp(files,'\d+','match');
nums = str2double([nums{:}]);
nums =
0 1 10 11 12 ...
regexp returns its matches as a cell-array, the second line converts it back to actual numbers.
We can now get an actual numeric order by sorting the resulting array:
[~,order] = sort(nums);
and then put the files in the correct order:
files = files(order);
This should (I haven't tested it, I don't have a folder full of numerically labelled files handy) produce a list of files like so:
files=
'0.tif'
'1.tif'
'2.tif'
'3.tif'
...
this is partially dependent on the version of matlab you have. If you have a version with findstr this should work well
num_files_to_rename = numel(name_array);
for ii=1:num_files_to_rename
%in my test i used cells to store my strings you may need to
%change the bracket type for your application
curr_file = name_array{ii};
%locates the period in the file name (assume there is only one)
period_idx = findstr(curr_file ,'.');
%takes everything to the left of the period (excluding the period)
file_name = str2num(curr_file(1:period_idx-1));
%zeropads the file name to 3 spaces using a 0
new_file_name = sprintf('%03d.tiff',file_name)
%you can uncomment this after you are sure it works as you planned
%movefile(curr_file, new_file_name);
end
the actual rename operation movefile is commented out for now. make sure the output names are as you expect before uncommenting it and renaming all the files.
EDIT there is no real error checking in this code, it just assumes every file name has one and only one period, and an actual number as the name
The Batch file below do the rename of the files you want:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%f in ('dir /B *.tif') do (
set "name=00%%~Nf"
ren "%%f" "!name:~-3!.tif"
)
Note that this solution preserve the same order of your original files, even if there are missing numbers in the sequence..

Output from large .csv files generated by Matlab

I am downloading some data in static and time series format using Matlab codes (and toolboxes). The codes give out the results by default in a .csv file for static and time series separately. Although the static data turns out fine, the time series data is huge and the .csv file doesn't load all the data. I tried changing the output file extension to .dta and then also .mat in order to view the output in Stata or Matlab. Also tried writing a little loop where the data loaded into large .csv file can be split into two worksheets within the same file. But none of it has worked. Although I am used to some basic coding in Matlab, I am new to dealing with such large datasets. Any help on this would be very much appreciated.
Thank you- Veronica
How about using these two bits of VBScript to split your CSV file into 2 pieces. There will be 599,999 lines in the first output file (part1.csv) and the rest in the second file (part2.csv).
Save this as part1.vbs
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
LineNum=1
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
If LineNum<600000 Then
stdout.WriteLine(Line)
End If
LineNum=LineNum+1
Loop
Save this as part2.vbs
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
LineNum=1
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
If LineNum>=600000 Then
stdout.WriteLine(Line)
End If
LineNum=LineNum+1
Loop
Then you can do this at the Command Prompt to split your file in two:
cscript /nologo part1.vbs YourFile.CSV > part1.csv
cscript /nologo part2.vbs YourFile.CSV > part2.csv