Bash, normalize case in paths under dir - linux

I have a directory with files and other directories inside. I want to normalize all file paths inside it to lower-case. By this I mean that:
Whenever there are two paths ./A/b/d and /a/b/c under the directory (that I call .). Then A and a should be merged, with the name a. This can occur at any level.
Suppose that there are no file repetitions. That is, if all paths are converted to lowercase, there will be no file conflicts (but many directories will have to be merged).
How can I do this?
In case you are wondering, I am trying to copy a directory from linux to Mac (which is case-insensitive).

Related

Copying a file, but appending index if file exists

I have several directories with filenames being the same, but their data inside is different.
My program identifies these files (among many others) and I would like to copy all the matches to the same directory.
I am using shutil.copy(src,dst) but I don't want to overwrite files that already exist in that directory (previous matches) if they have the same name. I'd like to be able to append an integer if it already exists. Similar to the behavior in Windows10 when you copy where you can "keep both versions".
So for example, if I have file.txt in several places, the first time it would copy into dst directory it would be file.txt, the next time it would be file-1.txt (or something similar), and the next time it would be file-2.txt.
Are there any flags for shutil.copy or some other copy mechanism in Python that I could use to accomplish this?

In unix, are dot and double dot path or directory?

That is, do they take up storage space? Is dot a copy of the current directory? Could I say that dot and double dot are subdirectories of the current directory?
A directory is logically a table used to map names to filesystem objects such as files or directories. Files can have multiple names and can be in multiple directories. The extra directory entries are links to the same file; the file itself is not duplicated. The same is true for directories. The '.' entry is a name which always maps to the directory that it is in. '..' maps to the parent, but in the case of the root directory it maps to itself.

What is double dot(..) and single dot(.) in Linux?

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.

How to compare two rfs directories with `diff`?

I have two rfs dirctories I would like to compare to each other with diff. Both directories represent a rfs of some other system, and may contain links. If those links are absolute, they will point to something useless.
For example, I have one rfs with the following symlink (inside the rfs):
/usr/test -> /home/test/file1
Now I have this complete rfs inside a directory named /home/user/compare, and the absolute paths of both files mentioned above are
/home/user/compare/usr/test
/home/user/compare/home/test/file1
Clearly, the symlink /home/user/compare/usr/test does not point to the right file. And because of that a comparison with the files in /home/usr/compare with some other rfs directory will fail for those symlinks.
Is it possible to setup diff so it assumes not / as root but /home/user/compare as root (for the comparison), so that the given absolute symlink points to something valid, and diff takes it into account?
Maybe there is a similar Linux command I can use for that?

inotify --fromfile directive

I have a system fedora 15 with xfce window manager.
I installed an inotify util to play with.
I want to control, what happens with my files during my work process.
There is a command which i use today for running inotify
inotifywait --fromfile ~/list.inotify
That command easy read a list of folders and files to read and to ignore.
There is my list (list.inotify)
/home/alex
#/home/alex/Torrnets/
#/home/alex/.pulse-cookie
So it should read my home folder and ignore Torrents folder and .pulse-cookie file.
It ignores Torrents as well. But it won't ignore a .pulse-cookie file.
Any solution for this ? (please don't post a solution to use pattern based ignore, i want to work with a file list with absolute path's)
$man inotify
#<file>
When watching a directory tree recursively, exclude the specified file from being watched. The file must be specified with a relative or absolute path according to whether a relative or absolute path is given for watched directories. If a specific
path is explicitly both included and excluded, it will always be watched.
Note: If you need to watch a directory or file whose name starts with #, give the absolute path.
--fromfile <file>
Read filenames to watch or exclude from a file, one filename per line. If filenames begin with # they are excluded as described above. If <file> is `-', filenames are read from standard input. Use this option if you need to watch too many files to
pass in as command line arguments.
If you don't specify a -e argument, inotifywait will call inotify_add_watch with IN_ALL_EVENTS, which causes events to occur for files inside watched directories - note that inotify(7) says:
When monitoring a directory, the events marked with an asterisk (*) above can occur for files in the directory, in which case
the name field in the returned inotify_event structure identifies the name of the file within the directory.
If you have a look at the inotifywait code in question, you'll see that it only watches (and checks the exclude list against) directories. It would perhaps be a bit more user friendly if you were warned when specifying an exclusion that is not a directory or one that is never used, but that's the way it currently it is.

Resources