bug-findutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GNU mv and GNU find


From: Bernhard Voelker
Subject: Re: GNU mv and GNU find
Date: Tue, 21 May 2019 08:21:34 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1

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
> <address@hidden> 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]