I have a set of images located in a folder and I'm trying to read these images and store their names in text file. Where the order of images is very important.
My code as follow:
imagefiles = dir('*jpg');
nfiles = length(imagefiles); % Number of files found
%*******************
for ii=1:nfiles
currentfilename = imagefiles(ii).name;
% write the name in txt file
end
The images stored in the folder in the following sequence : {1,2,3,4,100,110}.
The problem that Matlab read and write the sequence of images as { 1,100,110,2,3,4}. Which is not the correct order.
How can this be overcome?
I would suggest to use scanf to find the number of the file. For that you have to create a format spec which shows how your file name is built. If it is a number, followed by .jpg, that would be: '%d.jpg'.
You can call sscanf (scan string) on the name's of the files using cellfun:
imagefiles = dir('*jpg');
fileNo = cellfun(#(x)sscanf(x,'%d.jpg'),{imagefiles(:).name});
Then you sort fileNo, save the indexes of the sorted array and go through these indexes in the for-loop:
[~,ind] = sort(fileNo);
for ii=ind
currentfilename = imagefiles(ii).name;
% write the name in txt file
end
Related
I have a directory with many files, which are named based on a given pattern, for instance: User_TR1_ES-ES.csv, User_TR1_FR-FR.csv User_TR2_DE-DE.csv. The destination directory contains subfolders like these: folder_TR1, folder_TR2. I need to copy each files that contain TR1 in the basename within directory folder_TR1, and successively with the rest of the files. My code so far:
#I made an array with the list of files in original folder
file_list = Dir.children(output)
#I captured the parts of the file name that I'm interested in two variables
file_list.each do |file|
user_chars = file[5] + file[6] + file[7]
lang_chars = file[9] + file[10] + "-" + file[12] + file[13]
end
#Now I create a new path, in order to make the copy
original_path = File.join(output, "User_#{user_chars}_#{lang_chars}.csv")
new_path = #where I'm having issues
#in order to make the copy, I'd make the following
FileUtils.cp(original_path, new_path)
I just can't proceed on copying from one place to the desired folder, by following their filenames. Any hint?
So taking a path like this:
path = "/path/to/User_TR1_ES-ES.csv"
You want to extract TR1 from it, you can use
id = File.basename(path).split("_")[1]
Now id will equal "TR1". From here you want to copy it, so you can just supply the destination folder:
target_dir = "/path/to/folder_#{id}"
FileUtils.copy path, target_dir
This is harder than I expected, but I have a folder with ~100 datasets in .csv format.
I would like to create a .csv file with the following fields:
The first field is the file's name. e.g. user_profile.csv
The second field is the file's absolute path, e.g. /Users/yuqli/project/user_profile.csv
I would like to do this with bash commands. But so far I have only be able to do :
ls >> out.csv
which will write all file names into a txt file... I see some people using a for loop, but manipulating lines in .csv file seems forbidding, and I don't know what to put inside the for loop...
Am I better off just using Python? Any help is appreciated... Thanks!
Thanks for the advice of gurus above, I came up with this Python program that 1) extracts file names and 2) extract field names in each file. Any comments are welcomed. Thanks!
import os
import csv
info = {} # store all information into a Python dictionary
for filename in os.listdir(os.getcwd()):
with open(filename, newline='') as f:
reader = csv.reader(f)
row1 = next(reader)
info[filename] = row1
path = os.getcwd()
header = 'field, dataset, path'
write_file = "output.csv"
with open(write_file, "w") as output:
output.write(header + '\n')
for key, value in info.items():
for elem in value:
curr_path = path + key
line = '{0}, {1}, {2}'.format(elem, key, curr_path)
output.write(line + '\n')
I have a script that outputs URLs based on input data. Each line of input generates roughly 20 URLs. This output is then used to upload to Akamai Content Control. However, Akamai has a limit on file size set to 50KB.
I know I can write a URL and then check file size. If file size breaks buffer, close that file and create a new one and repeat.
I am ultimately curious if there is a far more elegant way to handle this within Ruby with less overhead/code.
Thanks
Before writing each line check if file size + line size is less then limit. Write to file or create new one accordingly.
index = 2;
f = File.new('output_file.txt', 'w')
while(there_is_new_output_to_write) do #get new line
if(f.size + output_line.size > LIMIT) do #if total size is too big
Fileutils.cp('output_file.txt','output_file' + index + '.txt') #copy
index = index + 1 #increment index for new file
f = File.new('output_file.txt', 'w') #override output file
end
f.puts(output_line) #write new line
end
#here You will have index -1 files
#that is if index is 4, then you will have output_file.txt, output_file2.txt, output_file3.txt,
#but NOT output_file4.txt!
Alternatively if that is not a problem You can use some good archiving tool out there to splice files to 50kb size for You.
I want to copy all images in a file to another file with different names. But, images order changes during copy. For example, this order like that: B0. jpg,B1.jpg,..,B9.jpg,B10.jpg,B11.jpg..,B30.jpg. I want to change the name of B0.jpg to image1.jpg, B1.jpg to image2.jpg in a similar. But, it changes B0.jpg to B10.jpg and then B11.jpg instead of B1,B2,B3...Because of that images order changed. How can I fix this problem?
The problem is the SO orders the file names using ASCII sorting, as they're strings (it doesn't look to numbers differently). The string "10" is placed before the string "2", because "1" < "2".
Instead of relying on the order, you could do something like this:
imgs = dir('*.jpg');
for i = 1:numel(imgs)
% Change the 'B' to 'image'
newName = strrep(imgs(i).name, 'B', 'image');
% Copy the image
copyfile(imgs(i).name, ['c:\destination\' newName]);
end
I am writing a function for remote sensing purposes using matlab
the user will enter a folder containing 7 files into the program each file is a band of an image and the names of them is:
"b1.dat"
"b2.dat"
"b3.dat"
"b4.dat"
"b5.dat"
"b6.dat"
"b7.dat"
for example if 2 is entered as the argument of the function it will search in seven file names that are in the access and then will show b2.dat
how do you suggest me to write the code
You can use uigetfiles to select the directory and dir to get a list of the folders contents. Once you have the list, strfind will tell you a file contains a given number.
Or, using uigetdir:
dirName = uigetdir('C:\', 'select a directory');
contents = dir(dirName);
for c = contents
name = c.name;
if strfind(name,'3')
fileToOpen = name{1};
end
end
I used these two lines of codes:
folder = uigetdir('D:\','Select the folder containing bands')
filenames = dir(folder)
the first line returns the path to the folder as I expected:
folder =
D:\RS\911130 TM bands
but the second line not. I have 7 files in my folder and it returns a 9x1 struct
filenames =
9x1 struct array with fields:
name
date
bytes
isdir
datenum
for example the contents of the filenames(1,1) is: