Linux: Compare repertories with a loop - linux

I would like to compare two directories, and be able to copy one file from a directory to an other ( for example, copy the file dog.png from the directory 1 to the directory 2 if this one doesn't have this file)
I know that there is the "diff" command diff -rq rep1 rep2 which include recursion, but I don't think that the result is convenient (the way it's presented) to work with it. Plus , it doesn't care about the path as long as there is the same file somewhere in the second directory.
My idea was to list the elements of the rep1 , then do a loop, and if there is an other directory, open it and do another loop, do that until there are only files and then compare and go back to the previous loop. I know that seems like recursion, I wanted to know if it was possible to make it that way ? Or if it's too complex.

Mike C: Welcome to Stack Overflow! I would try posing this Q to another site https://softwareengineering.stackexchange.com/ as it does not quite fit the "norm" for Stack Overflow where usually you ask questions about concrete code.I'm going to try to answer the Q anyways.
Yes you could solve this with recursion. You would make one function or method that takes the full path to a directory as it's input, then that function would list all sub-directories and call itself on each of them.
The fact taht you will be scanning two directories in paralelle will add some complexity, because you have to decide what to do in 3 cases:
Subdir exists only in A
Subdir exists only in B
Subdir exists in both
I would implement this by passing TWO full paths to the function, and simply change behsaviour when one of them was null.

Related

What point in time does the Rust glob function represent?

The Rust glob crate is fairly straight forward, as long as no files are added during execution. But what happends if the state of the filesystem changes?
Consider the following situation:
// The folder contains a cute giraffe and a cute zebra.
let mut animals = glob("images/cute_*.jpg");
// A cute cat is added to the folder.
let first = animals.next();
// A cute dog is added to the folder.
let second = animals.next();
What will first and second be? A giraffe and a zebra? A cat and a dog?
To rephrase the question in more technical terms: Does glob represent a snapshot of the filesystem as it was when it is called? Or perhaps when iteration begins? Or is "live" finding recently added files?
Looking at the source code for glob, you can see that:
It doesn't really do anything until the first time you call next, so in your example it would see the cat.
It reads the whole directory at once the first time it is needed, so in your example it would not see the dog.
When your pattern matches several directories, it reads them one by one, so any files that are added to a directory before it starts processing that specific directory will be visible. Once processing of the directory has started, the list is frozen and new files will not be seen.
In your example, it would therefore return the giraffe, zebra and cat in no particular order.
Note however that this is looking at the code as it currently stands, behaviour may change if the code is modified.

Executing functions stored in a string

Lets say that there is a function in my Delphi app:
MsgBox
and there is a string which has MsgBox in it.
I know what most of you are going to say is that its possible, but I think it is possible because I opened the compiled exe(compiled using delphi XE2) using a Resource Editor, and that resource editor was built for Delphi. In that, I could see most of the code I wrote, as I wrote it. So since the variables names, function names etc aren't changed during compile, there should a way to execute the functions from a string, but how? Any help will be appreciated.
EDIT:
What I want to do is to create a simple interpreter/scripting engine. And this is how its supposed to work:
There are two files, scr.txt and arg.txt
scr.txt contains:
msg_show
0
arg.txt contains:
"Message"
And now let me explain what that 0 is:
First, scr.txt's first line is function name
second line tells that at which line its arguments are in the arg.txt, i.e 0 tells that "Message" is the argument for msg_show.
I hope my question is now clear.
I want to make a simple scripting engine.
In order to execute arbitrary code stored as text, you need a compiler or an interpreter. Either you need to write one yourself, or embed one that already exists. Realistically, the latter option is your best option. There are a number available but in my view it's hard to look past dwscript.
I think I've already solved my problem! The answer is in this question's first answer.
EDIT:
But with that, as for a workaround of the problem mentioned in first comment, I have a very easy solution.
You don't need to pass all the arguments/parameters to it. Just take my example:
You have two files, as mentioned in the question. Now you need to execute the files. It is as simple as that:
read the first line of scr.txt
check if it's a function. If not, skip the line
If yes, read the next line which tells the index where it's arguments are in arg.txt
pass on the index(an integer) to the "Call" function.
Now to the function which has to be executed, it should know how many arguments it needs. i.e 2
Lets say that the function is "Sum(a,b : integer)".It needs 2 arguments
Now let the function read the two arguments from arg.txt.
And its done!
I hope it will help you all.
And I can get some rep :)

Fast directory clean-up with Perl

I have a need to clean-up directory with millions of log files on my webserver. And I've found this great article on how to do this. There is, however, a couple interesting things in that one-liner, which I am interested in.
Here's the Perl code I am interested in:
for(<*>){((stat)[9]<(unlink))}
Runned with perl -e 'code'.
So, here are my questions:
the for(<*>) construction - I assume it iterates through the files in the current directory. But where does it store the iterator?
the stat and unlink functions expect at least one argument, I assume... But where is it?
why the result of calling (stat)[9] is compared to the result of calling (unlink)? And what does it results in?
Sorry, I am a no-perl-ish guy, thus I do not understand all those Perl abbreviations. That's why I am asking this question.
Thanks!
That one liner takes many shortcuts:
The <*> is a special case of the diamond operator. You can't access an iterator object, like in other languages. Here, it calls the glob function. In list context it returns a list from all the results (which are either lines of a file, or, as in your case, contents of a diretory. The return value of that is passed to for which iterates over a list and aliases the values in $_. $_ is the "default variable" for many functions…
Which brings us here. Many core functions default to $_ with no argument. So do unlink and stat.
(stat)[9] means execute stat in list context and select the 10th result (indices start at zero, this is the modify time). (compare that to an array access like $foo[9]).
The code
for(<*>){((stat)[9]<(unlink))}
is equivalent to:
for my $file (<*>) {
my $mtime = (stat($file))[9];
$mtime < unlink($file);
}
<*> can also be replaced with glob "*" which might be more readable.
The code will delete all files in the current directory. It will not delete directories.
Note that the last statement in the loop is completely redundant. If use warnings is in effect, it will give the warning:
Useless use of numeric lt (<) in void context
For this code to make sense, I would expect a comparison that actually matters, like comparing $mtime to some time to know which logs are old, e.g.:
if ($mtime < $oldtime) {
unlink $file or die "Cannot unlink $file: $!";
}
Note also that it might be prudent to check for failure when deleting files.
the for(<*>) construction - I assume it iterates through the files in the current directory. But where does it store the iterator?
for-loops can be used to iterate over arrays/lists, so if <*> produces a list, then your code is just a run of the mill for loop. As it turns out <*> is another way to spell glob(), which is sort of like a regex for retrieving file names, and glob() returns a list in list context--which is the context a for loop provides. See: http://perldoc.perl.org/functions/glob.html.
Note that the single quotes keep the shell from expanding the *, which would prevent perl from ever seeing it.

How can I copy picture and text from one file into another file dynamically using node.js

Suppose i have two files a_b_c_d.txt and e_f_g_h.png S,At runtime i.e., by using command prompt i have to create b folder inside that c folder inside that d folder inside that a.txt and same also for another file f->g->h->e.png and i have some text in a and image in epng . .So,how can I get values from those existing file into created files. .
You can find all the file system operations inside the fs module. http://nodejs.org/api/fs.html
But like tapan says if you need to do complex synchronous execution that manipulates the file system something like Bash will be a lot better suited for that.
So if I'm understanding you correctly you want to take a file named "a_b_c_d.txt" in some folder, and move that into a nested folder as:
./a_b_c_d.txt -> ./b/c/d/a.txt
The general solution would be:
Grab the file name using process.argv if it varies.
For example, if you supply the file as an argument to node, e.g.
node move.js "a_b_c_d.txt", the argument, "a_b_c_d.txt", will be in the argv array.
Process the file name using a combination of string and array methods.
Nodes current directory is stored in the __dirname global variable
if you need it.
You can split the extension from the rest of the path
using string's split(...) method.
For the above argument, split('.') will result in the array ['a_b_c_d', 'txt']
You can then split 'a_b_c_d' using '_',
and use various array operations to pull the file name 'a'
out of the array, so that you're left with the path ['b', 'c', 'd']
and the file name and extension sitting in their own variables somewhere.
Use fs.mkdirSync(...) on the path array to make each nested folder,
starting with b (e.g. using array's forEach(...) method).
You could also use the async fs.mkdir(...) and supply callbacks,
but the sync version is easier in this case.
Finally use fs.renameSync(...) to move ./a_b_c_d.txt to ./b/c/d/a.txt.
As you can see, python or bash (as tapan suggested) would probably be simpler for this use case, but if for some reason you have to use node, the above advice will hopefully be enough to get you started.

Directory.GetFiles does not work as expected

string[] list = Directory.GetFiles("c:\\", "One Two Three - User.xml")
This code does not returns me array, but I have three directories with this file. Any ideas how to make it work?
Check out the variation of this method that takes a SearchOption, here. It seems that you're after a recursive direction search, and the SearchOption enumeration allows you to specify this.
Directory.GetFiles does not traverse subdirs in this way... so only file on C:\ is returned!!
If you need to search this pattern in a dir and in its subdirs you have to scan (recursively) all subdirs and then current dir. In every step you add files to a global variable (string[] files).
I think this example can be useful...
Or you can use Directory.GetFiles(path, pattern, SearchOption.AllDirectories);

Resources