Hi Bernhard, Many thanks for your email.
Yours, Gabriele On Tue, May 21, 2019 at 8:21 AM Bernhard Voelker <m...@bernhard-voelker.de> wrote: > > Hi, > > it's much better to discuss such things on a mailing list than via direct > email contact --> therefore I'm adding the GNU findutils mailing list. > > (Looking at the easiest solution - see below -, I could've also added the > GNU coreutils mailing list.) > > On 5/17/19 2:32 PM, Gabriele Laurenzi wrote: > > Adding rms to this email > > > > Many thanks again, > > > > gl > > > > On Fri, May 17, 2019 at 2:31 PM Gabriele Laurenzi > > <laurenzi.gabri...@gmail.com> wrote: > >> > >> Hello, > >> > >> I am Gabriele, and I have a curiosity regarding mv and find, that I > >> would ask to you (this is not work related; I do also use GNU Linux > >> for personal use at home). > >> > >> At home, I had like 4-5 subdirectories in a directory named > >> "parent-dir", structure of that fs is as this: > >> > >> parent-dir _ dir1 > >> _ dir2 > >> _ dir3 > >> _ dir4 > >> > >> In dir1, dir2, dir3, dir4 I have respectively something like 1000 > >> files, and 300 of them or so are duplicated (same name, same content, > >> different indexing) in the directory tree. I made a one liner script > >> to put all the contents of these four directories in the path above > >> (../) > >> > >> Now, a file manager like for instance Caja (MATE) or alike would have > >> asked me to replace file x with file y (same name and content) based > >> on timestamps, but the one-liner I made was like > >> > >> find . -type f -mindepth 2 -exec mv -i -- {} . \; > > Please use the -mindepth option before any non-option argument (-type). > You should've got a warning like: > > find: warning: you have specified the -mindepth option after a non-option \ > argument -type, but options are not positional (-mindepth affects tests \ > specified before it as well as those specified after it). Please specify \ > options before other arguments. > > >> This automatically moves the content of the subdirectories in the > >> directory "parent-dir". But obviously enough it does replace the file > >> with the same content and name, so like 40-50 GB of space on disk was > >> freed. > >> > >> I am fine with this, however, I wanted to decide basing on the last > >> updated file to be saved, in this case I instead got files replaced (I > >> guess) based on alphabetical order as soon as "find" util did find the > >> files in the subdirectories. > > So you only want to move the file "down" to the current directory if it > is newer than the one in the destination? That sounds like you would > ask for 'mv --update' (or the short -u option of 'mv'): > > $ months='January February March April May' > > $ mkdir $months > > $ for month in $months ; do for day in 1 2 3; do touch --date="${month} > ${day}" ${month}/file${day}; done; done > > $ find . -type f -exec ls -log '{}' \; > -rw-r--r-- 1 0 Mar 2 00:00 ./March/file2 > -rw-r--r-- 1 0 Mar 3 00:00 ./March/file3 > -rw-r--r-- 1 0 Mar 1 00:00 ./March/file1 > -rw-r--r-- 1 0 Jan 2 00:00 ./January/file2 > -rw-r--r-- 1 0 Jan 3 00:00 ./January/file3 > -rw-r--r-- 1 0 Jan 1 00:00 ./January/file1 > -rw-r--r-- 1 0 Apr 2 00:00 ./April/file2 > -rw-r--r-- 1 0 Apr 3 00:00 ./April/file3 > -rw-r--r-- 1 0 Apr 1 00:00 ./April/file1 > -rw-r--r-- 1 0 Feb 2 00:00 ./February/file2 > -rw-r--r-- 1 0 Feb 3 00:00 ./February/file3 > -rw-r--r-- 1 0 Feb 1 00:00 ./February/file1 > -rw-r--r-- 1 0 May 2 00:00 ./May/file2 > -rw-r--r-- 1 0 May 3 00:00 ./May/file3 > -rw-r--r-- 1 0 May 1 00:00 ./May/file1 > > $ find . -mindepth 2 -type f -print -exec mv -vu -- '{}' . \; > ./March/file2 > renamed './March/file2' -> './file2' > ./March/file3 > renamed './March/file3' -> './file3' > ./March/file1 > renamed './March/file1' -> './file1' > ./January/file2 > ./January/file3 > ./January/file1 > ./April/file2 > renamed './April/file2' -> './file2' > ./April/file3 > renamed './April/file3' -> './file3' > ./April/file1 > renamed './April/file1' -> './file1' > ./February/file2 > ./February/file3 > ./February/file1 > ./May/file2 > renamed './May/file2' -> './file2' > ./May/file3 > renamed './May/file3' -> './file3' > ./May/file1 > renamed './May/file1' -> './file1' > > $ find . -type f -exec ls -log '{}' \; > -rw-r--r-- 1 0 Jan 2 00:00 ./January/file2 > -rw-r--r-- 1 0 Jan 3 00:00 ./January/file3 > -rw-r--r-- 1 0 Jan 1 00:00 ./January/file1 > -rw-r--r-- 1 0 May 2 00:00 ./file2 > -rw-r--r-- 1 0 May 3 00:00 ./file3 > -rw-r--r-- 1 0 Feb 2 00:00 ./February/file2 > -rw-r--r-- 1 0 Feb 3 00:00 ./February/file3 > -rw-r--r-- 1 0 Feb 1 00:00 ./February/file1 > -rw-r--r-- 1 0 May 1 00:00 ./file1 > > I added a -print to 'find' and -v to 'mv' to see what's going on. > As the January and February directories have processed later, the destination > file is already newer, and therefore 'mv -u' skips those files. > > An alternative to 'mv -u' would be to check explicitly in a shell action > if the source is newer than the destination: > > $ find . -mindepth 2 -type f \ > -exec sh -c 'test "$1" -nt "$(basename "$1")" \ > && mv -v "$1" . \ > || echo "skipping $1"\ > ' sh '{}' . \; > renamed './March/file2' -> './file2' > renamed './March/file3' -> './file3' > renamed './March/file1' -> './file1' > skipping ./January/file2 > skipping ./January/file3 > skipping ./January/file1 > renamed './April/file2' -> './file2' > renamed './April/file3' -> './file3' > renamed './April/file1' -> './file1' > skipping ./February/file2 > skipping ./February/file3 > skipping ./February/file1 > renamed './May/file2' -> './file2' > renamed './May/file3' -> './file3' > renamed './May/file1' -> './file1' > > Obviously, this is more complex. > > >> I did not thought of enabling the -i (interactive flag mode) for find. > > I don't understand: there is no -i option for find. > > >> I would like to know how find and mv manages a situation like this; > >> can you answer me? > >> > >> Many thanks for Your time and effort in replying to me, it is very > >> appreciated. > >> > >> Gabriele Laurenzi > > Have a nice day, > Berny