how to make gulp.dest dynamic - coffeescript

I am learning to use gulp.I took a eg scenario in which I tried to copy the files based on the name if it is odd move it to odd folder otherwise move it to even. But some where destination folder is messed up. here is the folder structure and code.
1
--my
----new
-----2.txt
----1.txt
----2.txt
g = gulp.src '**/*.txt', cwd: '1'
g.pipe map (file,cb)->
filename = path.basename file.path, path.extname(file.path)
if filename % 2
dest = 'odd'
else
dest = 'even'
debugger
console.log 'destination ',dest
g.pipe gulp.dest dest
cb null,file
It is copying the even file names to odd folder.It is about the destination folder being remembered(closure I think)

If you literally only have two output destinations, the simplest solution might be to use the gulp-if plugin, like so (I don't use CoffeeScript, so you'll have to convert it yourself):
var _if = require('gulp-if');
function fileIsOdd(file) {
return path.basename(file.path, path.extname(file.path)) % 2;
}
// in your task
gulp.src('**/*.txt', {cwd: '1'})
.pipe(_if(fileIsOdd, gulp.dest('odd'), gulp.dest('even')))
What this does is process the individual file with the fileIsOdd function. If the function returns a truthy value, then the first argument is processed, otherwise the second argument is processed.

Related

Having trouble conditionally moving files based on their names

I am trying to write a script that will auto sort files based on the 7th and 8th digit in their name. I get the following error: "Argument must be a string scalar or character vector". Error is coming from line 16:
Argument must be a string scalar or character vector.
Error in sort_files (line 16)
movefile (filelist(i), DirOut)
Here's the code:
DirIn = 'C:\Folder\Experiment' %set incoming directory
DirOut = 'C:\Folder\Experiment\1'
eval(['filelist=dir(''' DirIn '/*.wav'')']) %get file list
for i = 1:length(filelist);
Filename = filelist(i).name
name = strsplit(Filename, '_');
newStr = extractBetween(name,7,8);
if strcmp(newStr,'01')
movefile (filelist(i), DirOut)
end
end
Also, I am trying to make the file folder conditional so that if the 10-11 digits are 02 the file goes to DirOut/02 etc.
First, try avoid using the eval function, it is pretty much dreaded as slow and hard to understand. Specially if you need to create variables. Instead do this:
filelist = dir(fullfile(DirIn,'*.wav'));
Second, the passage:
name = strsplit(Filename, '_');
Makes name a list, so you can access name{1} or possibly name{2}. Each of these are strings. But name isn't a string, it is a list. extractBetween requires a string as an input. That is why you are getting this problem. But note that you could have simply done:
newStr = name(7:8);
If name was a string, which in Matlab is a char array.
EDIT:
Since it has been now claimed that the error occurs on movefile (filelist(i), DirOut), the likely cause is because filelist(i) is a struct. Wheres a filena name (char array) should have been given at input. The solution should be replacing this line with:
movefile(fullfile(filelist(i).folder, filelist(i).name), DirOut)
Now, if you want to number the output folders too, you can do this:
movefile(fullfile(filelist(i).folder, filelist(i).name), [DirOut,filesep,name(7:8)])
This will move a file to /DirOut/01. If you wanted /DirOut/1, you could do this:
movefile(fullfile(filelist(i).folder, filelist(i).name), [DirOut,filesep,int2str(str2num(name(7:8)))])

Faster copyfiles Matlab

I have a folder origin_training with subfolders like FM, folder1, folder2, ... . I can get the list of image files in .png format into a cell called FM.
FM_dir = fullfile(origin_training, 'FM');
FM = struct2cell(dir(fullfile(FM_dir, '*.png')))';
My goal is to match the names in my folder with the images in my cd, and make a new folder FM with the images from cd. Image names in the two paths are identical. I can do that with:
% mother_folder = '...' my current directory
filenames = FM(:,1);
destination = fullfile(mother_folder, 'FM', FM(:,1));
cellfun(#copyfile,filenames, destination);
This is really slow. Takes minutes even for small amounts of images (~30).
My current directory has ~ 10000 images (the ones that correspond to FM, folder2, folder3, ...). What am I missing here?
An alternative would be to create a shell command and execute it. Assuming FM contains full paths for each file, or relative paths from the current directory, then:
FM_dir = fullfile(origin_training, 'FM');
destination = fullfile(mother_folder, 'FM');
curdir = cd(FM_dir);
FM = dir('*.png');
cmd = ['cp ', sprintf('%s ',FM.name), destination];
system(cmd);
cd(curdir);
If you're on Windows, replace 'cp' by 'copy'.
Note that here we're not creating a shell command per file to be copied (presumably what copyfile does), but a single shell command that copies all files at once. We're also not specifying the name for each copied file, we specify the names of the files to be copied and where to copy them to.
Note also that for this to work, mother_folder must be an absolute path.
I somehow put my code into a function and now it works at expected speed. I suspected that cd had to do with the low speed so I am only passing the full directories as character vectors.
The same approach works for my purpose or with a slight modification to just copy from A to B. As now, it works to match files in A to those on B and copy to B/folder_name
function [out] = my_copyfiles(origin_dir, folder_name, dest_dir, extension)
new_dir = fullfile(origin_dir, folder_name);
% Get a cell with filenames in the origin_dir/folder_name
% Mind transposing to have them in the rows
NEW = struct2cell(dir(fullfile(new_dir, extension)))';
dest_folder = fullfile(dest_dir, folder_name);
% disp(dest_folder)
if ~exist(dest_folder, 'dir')
mkdir(dest_folder)
end
%% CAUTION, This is the step
% Use names from NEW to generate fullnames in dest_dir that would match
filenames = fullfile(dest_dir, NEW(:,1));
destination = fullfile(dest_folder, NEW(:,1));
% if you wanted from origin, instead run
% filenames = fullfile(new_dir, NEW(:,1));
% make the copies
cellfun(#copyfile,filenames, destination);
%Save the call
out.originDir = new_dir;
out.copyFrom = dest_dir;
out.to = dest_folder;
out.filenames = filenames;
out.destination = destination;
end

Saving figure without providing filename [duplicate]

this question about matlab:
i'm running a loop and each iteration a new set of data is produced, and I want it to be saved in a new file each time. I also overwrite old files by changing the name. Looks like this:
name_each_iter = strrep(some_source,'.string.mat','string_new.(j).mat')
and what I#m struggling here is the iteration so that I obtain files:
...string_new.1.mat
...string_new.2.mat
etc.
I was trying with various combination of () [] {} as well as 'string_new.'j'.mat' (which gave syntax error)
How can it be done?
Strings are just vectors of characters. So if you want to iteratively create filenames here's an example of how you would do it:
for j = 1:10,
filename = ['string_new.' num2str(j) '.mat'];
disp(filename)
end
The above code will create the following output:
string_new.1.mat
string_new.2.mat
string_new.3.mat
string_new.4.mat
string_new.5.mat
string_new.6.mat
string_new.7.mat
string_new.8.mat
string_new.9.mat
string_new.10.mat
You could also generate all file names in advance using NUM2STR:
>> filenames = cellstr(num2str((1:10)','string_new.%02d.mat'))
filenames =
'string_new.01.mat'
'string_new.02.mat'
'string_new.03.mat'
'string_new.04.mat'
'string_new.05.mat'
'string_new.06.mat'
'string_new.07.mat'
'string_new.08.mat'
'string_new.09.mat'
'string_new.10.mat'
Now access the cell array contents as filenames{i} in each iteration
sprintf is very useful for this:
for ii=5:12
filename = sprintf('data_%02d.mat',ii)
end
this assigns the following strings to filename:
data_05.mat
data_06.mat
data_07.mat
data_08.mat
data_09.mat
data_10.mat
data_11.mat
data_12.mat
notice the zero padding. sprintf in general is useful if you want parameterized formatted strings.
For creating a name based of an already existing file, you can use regexp to detect the '_new.(number).mat' and change the string depending on what regexp finds:
original_filename = 'data.string.mat';
im = regexp(original_filename,'_new.\d+.mat')
if isempty(im) % original file, no _new.(j) detected
newname = [original_filename(1:end-4) '_new.1.mat'];
else
num = str2double(original_filename(im(end)+5:end-4));
newname = sprintf('%s_new.%d.mat',original_filename(1:im(end)-1),num+1);
end
This does exactly that, and produces:
data.string_new.1.mat
data.string_new.2.mat
data.string_new.3.mat
...
data.string_new.9.mat
data.string_new.10.mat
data.string_new.11.mat
when iterating the above function, starting with 'data.string.mat'

Saving file with part of file name and date

Hi there I'm currently trying to find a way to save 2 variables from my workspace into a file. I want the file name to be put together using the original and the current date.
I only want the max value from the variables so:
max(streaking)
and
max(tap_total)
The original file name is:
3_FM001_02_05460$BandP$64_24000_FWD_1x1_PRI_PRI_PRI_PRI_15_17_ActivePixelMeans.csv
The only portion of this original file name that I would like to use is:
3_FM001_02_05460$BandP$64_24000_FWD_1x1
These can be saved in a text file or spreadsheet, it doesnt matter.
An example of the new file name would be something like this:
3_FM001_02_05460$BandP$64_24000_FWD_1x1_7-26-2012
Also,
If something could be done in the file to display which variable is which, for example:
Streaking: 1.272 % this would come from the variable max(streaking)
Tap_Total: 2.252 % this would come from the varaible max(tap_total)
EDIT:
% Construct a questdlg with three options
choice = questdlg('Would you like to save?', ...
'Save Options', ...
'Yes','No','Cancel','Cancel');
% Handle response
switch choice
case 'Yes'
disp([choice ' processing.'])
save_option = 1;
case 'No'
disp([choice ' processing.'])
save_option = 0;
case 'Cancel'
disp('Canceled.')
save_option = 2;
end
file_to_get = evalin( 'base', 'file_to_get' );
streaking = evalin( 'base', 'streaking' );
tap_total = evalin( 'base', 'tap_total' );
if save_option == 0
elseif save_option == 1
max_streak = max(streaking);
max_tap = max(tap_total);
str_streak = mat2str(max_streak);
str_tap = mat2str(max_tap);
fname = file_to_get;
pruned_fname = regexprep(fname,'_PRI(\w*).(\w*)','');
new_fname = [pruned_fname '_' date '.csv'];
path1 = '\\pfile01thn\bbruffey$\My Documents\analysis data\Banding and Streaking Results';
fid = fopen([path1 new_fname], 'w');
fprintf(fid,['Max Banding: %s\nMax Streaking: %s'],str_tap,str_streak)
fclose(fid);
elseif save_option == 2
end
This would be a great place to use the regexprep command to prune the original filename down.
Example:
fname = '3_FM001_02_05460$BandP$64_24000_FWD_1x1_PRI_PRI_PRI_PRI_15_17_ActivePixelMeans.csv';
pruned_fname = regexprep(fname,'_PRI(\w*).(\w*)','');
pruned_fname =
3_FM001_02_05460$BandP$64_24000_FWD_1x1
Now, a note about the regexprep command I used here. This is specific for the filename you provided here. Since it looks like you want to trim off everything after the the first _PRI I used a tag (\w*) which means any combination of [a-z A-Z _ 0-9] can follow. Notice that since this is a filename there is a . there hence why I added a period in and followed that with another (\w*) to finish out the csv. You can find more info on these sorts of operators here.
Now that you have the pruned_fname you can simply add whatever you want to it. So if you want to add the date in with an underscore to space it just simply do something like this:
new_fname = [pruned_fname '_' date '.csv'];
new_fname =
3_FM001_02_05460$BandP$64_24000_FWD_1x1csv_26-Jul-2012.csv
Now you simply need to open the file to write to it. you might need to append the path to where you want to save it, I'm just going to call it path for now. It would be something like C:\Documents\
fid = fopen([path new_fname], 'w')
Now with the fid you have the id of the file you want to write to. This should be a new file and if it isn't you are going to overwrite the file contents if you do it this way. Just be aware =)
Next you can simply write those first two lines to the file using fwrite fprintf, just to name a few possible functions.
Hopefully that'll get you setup there!

What do I have to add at the beginning of this loop?

how I can read the following files using the for loop: (can the loop ignore the characters in filenames?)
abc-1.TXT
cde-2.TXT
ser-3.TXT
wsz-4.TXT
aqz-5.TXT
iop-6.TXT
What do I have to add at the beginning of this loop ??
for i = 1:1:6
nom_fichier = strcat(['MyFile\.......' num2str(i) '.TXT']);
You can avoid constructing the filenames by using the DIR command. For instance:
myfiles = dir('*.txt');
for i = 1:length(myfiles)
nom_fichier = myfiles(i).name;
...do processing here...
end
First of all, why would you use strcat here? This is, by itself, a SINGLE string. All concatenation has already been done by the brackets [].
['MyFile\.......' num2str(i) '.TXT']
Next, I'm not certain what is your question here. Is it how to load in the data? If the files are simply delimited numbers, with the same number of them on each line, then load will suffice to load them in, or perhaps you may need textread.
My guess is you do not know how to build the main part of of the file name. You might do it this way:
Names = {'abc' 'cde 'ser' 'wsz' 'aqz' 'iop'};
for i = 1:6
fn = ['MyFile',filesep,Names{i},'-',num2str(i),'.TXT'];
data = load(fn);
% do other stuff ...
end
If you don't want to create a variable with the names by typing them in, then use dir, perhaps like this to create a list of text file names:
Names = dir('MyFile\*.TXT');