Why does Matlab find '.' and '..' dirs when reading folder content using dir('')? [duplicate] - matlab

The ls -ai command shows that . and .. have their inodes the same as the current directory and parent directory, respectively.
What exactly are . and ..?
Are they real files or even hard links? But as I have known, it's not allowed to create a hard link to a directory.

. represents the directory you are in and .. represents the parent directory.
From the dot definition:
This is a short string (i.e., sequence of characters) that is added to
the end of the base name (i.e., the main part of the name) of a file
or directory in order to indicate the type of file or directory.
On Unix-like operating systems every directory contains, as a minimum,
an object represented by a single dot and another represented by two
successive dots. The former refers to the directory itself and the
latter refers to its parent directory (i.e., the directory that
contains it). These items are automatically created in every
directory, as can be seen by using the ls command with its -a option
(which instructs it to show all of its contents, including hidden
items).

They are special name-inode maps which do count as hard-links (they do increase the link-count) though they aren't really hard-links, since, as you said, directories can't have hard-links. Read more here: Hard links and Unix file system nodes (inodes)

. represents the current directory that you are using and
.. represents the parent directory.
Example:
Suppose you are in the directory /etc/mysql and you wanted to move to the parent directory, i.e. /etc/. Then use cd..:
/etc/mysql> cd ..
And if you wanted to set the path of one file in the current directory bash file, use . with file name like this: ./filename

They are not hard links. You can more think of it like a shorthand for this directory (.) and parent of this directory (..).
Try to remove or rename . or ... Then you understand why it is not a hard link.

Related

How to move files whose file name is not used in a set of text files?

I'm a Powershell beginner and this is my first post on stackoverflow. I can understand some simple pipelines, but the following challenge is too complicated for me at this point:
I have a folder with testdata containing *.bmp files and their associated files. I want a powershell script to check which bmp-files are still used. If not used, move bmp-files and associated files to another folder.
Details:
bmp-files and associated files: For example; car01.bmp, car01.log, car01.file, car02.bmp, (...)
The bmp-files are in use if their file name (eg, car01.bmp) is mentioned in any of the (text/csv) files in at least one of 2 locations (incl. subfolders).
If the file name is not found in any of the text files, I want the script to move that file, and any file who's name differs only by file extension to a designated folder.
Looking forward to your solutions!

MATLAB - Get current path and then use it to navigate to a different folder

I have a bunch of codes that are currently stored on my local machine. There are two folders, one called "Resources" and another called "src". There is one main script that needs to be run called "main.m" in "src" which calls files from "Resources".
If I copy this whole thing onto a new computer, the paths will change and MATLAB may not be able to find "Resources" anymore. I know that relative to "main.m", I need to go up one level and then into "Resources".
What is the best way of getting MATLAB to point to "Resources"?
I am currently trying along the lines of
P = mfilename('fullpath')
which gives the path for main.m. Now, I want to navigate from here, one folder up and then into "Resources". Or if there is a better way, please let me know.
Eventually, I want to extend it to work for multiple folders "Resources1", "Resources2" etc. so MATLAB needs to be able to navigate to the right folder.
You can get it like:
fullfile(fileparts(mfilename('fullpath')), '..', 'Resources');
Explanation:
mfilename('fullpath') will return the full path and name of the
M-file in which the call occurs, without the extension
fileparts will return the path of the passed file (only the containing directory)
fullfile will build the full directory specification from the folder names passed (Note: '..' always means the parent directory)
Based on this it is quite simple to write a function that gets the sibling directory of the directory containing the file:
getSiblingOfParentDirectory.m
function siblingDirPath = getSiblingOfParentDirectory(filepath, siblingDirName)
siblingDirPath = fullfile(fileparts(filepath), '..', siblingDirName);
end
then to use it in an M-file:
for i = 1:3
disp(getSiblingOfParentDirectory(mfilename('fullpath'), ['Resources', num2str(i)]));
end
Sample output:
D:\pathtest\Resources1
D:\pathtest\Resources2
D:\pathtest\Resources3
You can try the following:
ResourcesFolder = strrep(mfilename('fullpath'), 'src\main', 'Resources');
addpath(ResourcesFolder);
%%Your code here where you need those files
rmpath(ResourcesFolder);
Which is fully dependant on the names of your folders & files of course. Basically "addpath" enables you to access the files in the mentioned directory by adding it to the search path, and "rmpath" does the exact opposite.
Also, if you literally want to navigate to a folder present on one level up, you can execute the following:
cd ..\Resources
Which goes one level up, searches for the folder 'Resources', then changes the current directory to that folder .

Open multiple subfolders within a loop

I have a folder named "Photos" that is a subfolder of the current directory. Inside that folder, there are four subfolders with names "Order1", "Order2",
"Order3", "Order4". I am trying to open these subfolders using a loop.
The following code is not working.
for i=1:4
current_path=pwd;
cd(current_path');
cd('Photos\Order%d',i);
end
There are a lot issues going on here at the same time.
The primary issue is that you are changing directories each time through the loop but you're also getting the value of the current directory (pwd) each time. The directory doesn't automatically reset to where you were when it goes back to the top of the loop. I think you expect current_path to be the folder you started in and be the same for all iterations.
You need to use sprintf or something similar to create your "OrderN" folder names. cd doesn't know what to do with the format specifier you're trying to use.
You should always use fullfile when concatenating file paths. Period.
You should use absolute paths when possible to remove the dependence upon the current directory.
Do you really need to change the working directory? If you're trying to load files within these folders, please consider using absolute file paths to the files themselves rather than changing folders.
If you are going to do this this way, please be sure to reset the path back to where it was at the end of the loop. There is nothing worse than running code and ending up in a directory that is different than where you were when you called it.
To actually make your code work, we could do something like this. But given all of my points above (specifically, 4-5), I would strongly consider a different approach.
startpath = pwd;
for k = 1:4
folder = fullfile(startpath, 'Photos', sprintf('Order%d', k));
cd(folder)
end
% Set the current directory to what it was before we started
cd(startpath)

How to write relative path in MATLAB?

I need to read a group of dat files so when I do this it is working all right.
list_of_files=dir(fullfile('/home/username/Desktop/Old/MTP/Generate/schemes/o33smnpimp/data/', '*.dat'));
The thing is I want to do this for number of schemes (like o33smnpimp) where every scheme folder has a data folder so I tried something like this but it's not working. What could be the problem?
list_of_files=dir(fullfile('../data/', '*.dat'));
My matlab file lies in o33smnpimp folder.
.. indicates the parent directory, . the current directory. your code looks in /home/username/Desktop/Old/MTP/Generate/schemes/ for the sub directory data, assuming your working directory is /home/username/Desktop/Old/MTP/Generate/schemes/o33smnpimp.
Use
list_of_files=dir(fullfile('./data/', '*.dat'));
or
list_of_files=dir(fullfile('data', '*.dat'));

Why do directory listings contain the current (.) and parent (..) directory?

Whenever I list the contents of a directory with a function like readdir, the returned file names also include "." and "..". I have the suspicion that these are just normal links in the file system and therefore indistinguishable from actual files, but I always have to filter them out because they are not actual objects in the directory I am listing. Is there a good reason for functions like readdir to include them? Do some operating systems or file systems contain more or different virtual file names? Is there a better way to filter them out other than by doing string comparison with "." and ".."?
Update: thank you all for answering. I suppose I always thought that things like ./ and ../ were mere conventions that could be handled by searching and replacing. I find it a bit surprising, though probably more efficient and transparent, to have them be part of the file system itself.
One question remains, though: since . and .. are arbitrary names for these links, are there file systems that use different ones?
. and .. are actually hard links in filesystems. They are needed so that you can specify relative paths, based on some reference path (consider "../sibling/file.txt"). Since these hard links are actually existing in the filesystem, it makes sense for readdir to tell you about them. (actually the term hard link just means some name that is indistinguishable from the actual directory referred to: they both point to the same inode in the filesystem).
Best way is to just strcmp and ignore them, if you don't want to list them.
Originally they were hard links, and the number of special cases in the filesystem code for . and .. were minimal. That's not true for all modern filesystems, however.
But the conventions have been established so that even filesystems where these two directory entries don't actually exist still report their existence through APIs like readdir. Changing this would now would break a lot of code.
I have the suspicion that these are
just normal links in the file system
and therefore indistinguishable from
actual files
They are. While you may perceive the file system as a hierarchy of "folders" "containing" folders, it is actually a doubly linked tree1, with directories being nodes and files being leafs. So, . and .. are needed links for accessing the leaves of the current node and for traversing the tree, and they are the same thing as all the other links.
When you call readdir, you get all the places you can directly go to from the current node. If you do not want to list places that you perceive as "up", you have to sort them out yourself. You should write a little function for that, perhaps called readdir_down. I do not know in which order readdir lists the directories, but perhaps you can just throw away the first two entries.
1) this is a first approximation, there are also "hard links" possible that make the tree actually a net.
One reason is that without them there is no way to get to the parent directory. Or get a handle to the current directory.
Without them, we cannot do such things as:
./run_this
Indeed, we couldn't add '.' to the $PATH, meaning we couldn't ever execute files that weren't already in the path.
These are normal directories, they are "hard links" to the current directory and directory above. They are present in all directories (even at the root level, where .. is exactly the same as .).
When using ls, you can filter out . and .. with ls -A (note the capital -A).
When applying a command to all dot-files, but not . or .., I often use .??* which matches only dot-file with a name of three characters or more.
touch .??*
Note this pattern also excludes any other file that begins with dot and is only two characters long (e.g. .x) but those files are uncommon.
When using programmatic file-listers like readdir() I do have to exclude . and .. manually. Since these two files are supposed to be first in the list returned by readdir() you can do this:
#files = readdir(DIR);
for (1..2) { shift #files; } # get rid of . and ..
# go on with your business
They are reported because they are stored in the directory listing. That's the way unices have always worked.
Because on Unix-like operating systems, the directory-listing commands include those, and you use them to move up and down in the filesystem hierarchy.
Something like grep { not /^.{1,2}\z/ } readdir HANDLE should work for you.
there is no good reason a directory scan should return these filenames.