Matlab fopen command responds to string but not variable equaling same string - matlab

I'm wondering if anyone can shed some light on the following issue with Matlab fopen command:
>> [stat myjob] = unix('echo $PBS_NODEFILE'); % gets PBS file name with allocated nodes
>> myjob
myjob =
/opt/torque/aux//66058.crunch.local
>> fid = fopen('/opt/torque/aux//66058.crunch.local')
fid =
3
>> fgetl(fid)
ans =
compute-9-2
>> fclose(fid);
I need the names of the nodes I have to control some later decisions in the script. The above can work if I'm in an interactive PBS job, but for the most part though I need to launch these jobs without intervention. When I try to do this by the stored filename:
>> fid = fopen(myjob) % returns invalid
fid =
-1
>> fgetl(fid)
??? Error using ==> fgetl at 44
Invalid file identifier. Use fopen to generate a valid file identifier.
Why, when I put in directly the value stored in myjob do I get a valid identifier, but when I put in myjob does it fail?
Thanks,
Andrew

Try this:
fid = fopen(deblank(myjob));
Looking at the way your output is formatted above, there appears to be an extra empty line appearing after the value of myjob is displayed, which indicates there may be a newline character appearing at the end of the string. This newline will cause the file name to not be recognized, so you can remove any trailing whitespace like this from a string with the function DEBLANK (or you can remove trailing and leading whitespace with the function STRTRIM).

Related

Issues with fopen understanding the filepath I am giving it

Basically, I build a list of files using ls, then want to loop through that list, read in a file, and do some stuff. But when I try to read the file in it fails.
Here is an example
r=ls(['Event_2006_334_21_20_11' '/*.r'])
Event_2006_334_21_20_11/IU.OTAV_1.0.i.r
which is a 1x80 char
fopen(r(1,:))
-1
but
fopen('Event_2006_334_21_20_11/IU.OTAV_1.0.i.r')
12 (or whatever its on)
works. I've tried string(r) and char(r) and sprintf('%s',r). If I just build the string like r = ['Event_2006_334_21_20_11' '/IU.OTAV_1.0.i.r'] it works. So it seems something about combining the different variable types that messes it up but I can't seem to find a workaround. Probably something obvious I'm missing.
Any suggestions?
ls returns a matrix of characters, which means each row contains the same number of characters. To indicate the problem, try:
['-' r(1,:) '-']
You will probably notice some whitespaces in front of the -. Unless you want to print the output to the command line, ls is not really useful. As mentioned by Alex, use dir instead.
A further tip regarding your last comment, concatenate file path using fullfile. It makes sure you get one file separator whenever concatenating:
>> fullfile('myfolder','mysubfolder','myfile.m')
ans = myfolder/mysubfolder/myfile.m
>> fullfile('myfolder/','mysubfolder','myfile.m')
ans = myfolder/mysubfolder/myfile.m
>> fullfile('myfolder/','/mysubfolder','myfile.m')
ans = myfolder/mysubfolder/myfile.m

How do I export a matrix in MATLAB?

I'm trying to export a matrix f that is double. My data in f are real numbers in three columns. I want a txt file as an output with the columns separated by tabs. However, when I try the dlmwrite function, just the first column appears as output.
for k = 1:10
f = [idx', firsttime', sectime'];
filename = strcat(('/User/Detection_rerun/AF_TIMIT/1_state/mergedlabels_train/'),(files_train{k,1}),'.lab');
dlmwrite(filename,f,'\t') ;
end
When I use dlmwrite(filename,f,'\t','newline','pc') ; I keep getting an error Invalid attribute tag: \t . I even tried 'tab' instead of '\t' but a similar error appears. Please let me know if you have any suggestions. thank you
This is because you are not calling dlmwrite properly. To specify the delimiter, you must use the delimiter flag, followed by the specific delimiter you want. In your case, you use \t. In other words, you need to do this:
for k = 1:10
f = [idx', firsttime', sectime'];
filename = strcat(('/User/Detection_rerun/AF_TIMIT/1_state/mergedlabels_train/'),(files_train{k,1}),'.lab');
dlmwrite(filename,f,'delimiter','\t') ;
end
BTW, you are using the newline flag with pc, meaning that you are specifying carriage returns that are recognized by a PC. I suggest you leave this out and allow MATLAB to automatically infer this. Only force the newline characters if you know what you're doing.
FWIW, the MATLAB documentation is pretty clear about delimiters and other quirks about the function: http://www.mathworks.com/help/matlab/ref/dlmwrite.html

Why does fprintf command display >> in MATLAB?

Here is a sample of a random script in MATLAB.
prompt = 'Please enter a lowercase x: ';
str = input(prompt, 's');
if str == 'x'
else
fprintf('Error, you did not enter a lowercase x.')
end
This always display what I have in the fprintf command with a >> at the end of it in the command window. For example, in this random context it would display ...
Error, you did not enter a lowercase x.>>
Simple question, yet I'm new to MATLAB. Why do I get a >> at the end of every fprintf command? Can't seem to figure it out.
You did not specify a line-break in your string, so fprintf pushes the text to the command windows and spawns another input prompt (the >>) directly after the text. Add a line break meta-character to the string (\n) to fix the issue:
fprintf('Error, you did not enter a lowercase x.\n')
Also, if your goal is to issue an error, you should use the error function. It halts execution of the code and colors the message red like other MATLAB errors.
Here the fprintf simply displays the text and returns to command console.
Use newline '\n' character,
fprintf('Error, you did not enter a lowercase x.\n');
% ~~~
to come back atfer newline with >> prompt

Preventing fgets from deleting first line

I'm opening a file, reading the first line using fgets, using regexp to test what format the file is in, and if the file is in the desired format, I use fscanf to read the entire file.
fid = fopen('E:\Tick Data\Data Output\Differentformatfiles\AUU01.csv','rt');
% reads first line of file but seems to be deleting the line:
str = fgets(fid);
% test for pattern mm/dd/yyyy
if(regexp(str, '\d\d/\d\d/\d\d\d\d'))
c = fscanf(fid, '%d/%d/%d,%d:%d:%d,%f,%d,%*c');
Unfortunately, if the contents of my file look like:
20010701,08:29:30.000,95.00,29,E
20010702,08:29:30.000,95.00,68,E
20010703,08:29:30.000,95.00,5,E
20010704,08:29:30.000,95.00,40,E
20010705,08:29:30.000,95.00,72,E
str will equal 20010701,08:29:30.000,95.00,29,E, but c will only equal the last 4 lines:
20010702,08:29:30.000,95.00,68,E
20010703,08:29:30.000,95.00,5,E
20010704,08:29:30.000,95.00,40,E
20010705,08:29:30.000,95.00,72,E
Is there a way to prevent fgets from deleting the first line? Or another function I should use?
It isn't actually erasing it, it's just moving on to the next line. You could either use a combination of fpos and fseek to go back to the beginning of that line, but since you've already got the line stored in str, I would add two lines:
if(regexp(str, '\d\d/\d\d/\d\d\d\d'))
c1 = sscanf(str, '%d/%d/%d,%d:%d:%d,%f,%d,%*c'); % scan the string
c2 = fscanf(fid, '%d/%d/%d,%d:%d:%d,%f,%d,%*c');
c = {c1;c2}; % concatenate the cells
It certainly isn't the most elegant solution, but it's robust and easy to shoehorn into your existing code.

MATLAB: How do you insert a line of text at the beginning of a file?

I have a file full of ascii data. How would I append a string to the first line of the file? I cannot find that sort of functionality using fopen (it seems to only append at the end and nothing else.)
The following is a pure MATLAB solution:
% write first line
dlmwrite('output.txt', 'string 1st line', 'delimiter', '')
% append rest of file
dlmwrite('output.txt', fileread('input.txt'), '-append', 'delimiter', '')
% overwrite on original file
movefile('output.txt', 'input.txt')
Option 1:
I would suggest calling some system commands from within MATLAB. One possibility on Windows is to write your new line of text to its own file and then use the DOS for command to concatenate the two files. Here's what the call would look like in MATLAB:
!for %f in ("file1.txt", "file2.txt") do type "%f" >> "new.txt"
I used the ! (bang) operator to invoke the command from within MATLAB. The command above sequentially pipes the contents of "file1.txt" and "file2.txt" to the file "new.txt". Keep in mind that you will probably have to end the first file with a new line character to get things to append correctly.
Another alternative to the above command would be:
!for %f in ("file2.txt") do type "%f" >> "file1.txt"
which appends the contents of "file2.txt" to "file1.txt", resulting in "file1.txt" containing the concatenated text instead of creating a new file.
If you have your file names in strings, you can create the command as a string and use the SYSTEM command instead of the ! operator. For example:
a = 'file1.txt';
b = 'file2.txt';
system(['for %f in ("' b '") do type "%f" >> "' a '"']);
Option 2:
One MATLAB only solution, in addition to Amro's, is:
dlmwrite('file.txt',['first line' 13 10 fileread('file.txt')],'delimiter','');
This uses FILEREAD to read the text file contents into a string, concatenates the new line you want to add (along with the ASCII codes for a carriage return and a line feed/new line), then overwrites the original file using DLMWRITE.
I get the feeling Option #1 might perform faster than this pure MATLAB solution for huge text files, but I don't know that for sure. ;)
How about using the frewind(fid) function to take the pointer to the beginning of the file?
I had a similar requirement and tried frewind() followed by the necessary fprintf() statement.
But, warning: It will overwrite on whichever is the 1st line. Since in my case, I was the one writing the file, I put a dummy data at the starting of the file and then at the end, let that be overwritten after the operations specified above.
BTW, even I am facing one problem with this solution, that, depending on the length(/size) of the dummy data and actual data, the program either leaves part of the dummy data on the same line, or bring my new data to the 2nd line..
Any tip in this regards is highly appreciated.