1

Due to an old backup concept I have some hard drives here, that contain file structures like:

/1.1
/2.1
/3.1
/FOLDER.DUPLICATE.$DRIVEBENDER/1.1
/FOLDER.DUPLICATE.$DRIVEBENDER/3.1
/FOLDER.DUPLICATE.$DRIVEBENDER/4.1
/Subfolder/1.2
/Subfolder/FOLDER.DUPLICATE.$DRIVEBENDER/2.2
/Subfolder/FOLDER.DUPLICATE.$DRIVEBENDER/3.2

The result should equal to the original structure, so all files in a folder called FOLDER.DUPLICATE.$DRIVEBENDER should be moved one level higher. If the file one level higher exists, the bigger file should win.

  • 1
    Biggest wins? Not newest? – Kusalananda Sep 10 '17 at 14:20
  • No, in this case really biggest wins. In the "raw" data, the sync (newest wins) worked. But as the "crash" began, some corruptet files came up and them were truncated. – nico Sep 10 '17 at 14:22
0

Assuming you don't have FOLDER.DUPLICATE.$DRIVEBENDER directories inside other FOLDER.DUPLICATE.$DRIVEBENDER directories, you could do something like:

find . -path '*/FOLDER.DUPLICATE.$DRIVEBENDER/*' -prune -type f -print0 |
  perl -0lne '
    if (m{(.*)/FOLDER.DUPLICATE.\$DRIVEBENDER/(.*)}s) {
      $upperfile = "$1/$2";
      if (-s > -s $upperfile) {
        rename $_, $upperfile or warn "rename $_: $!\n";
      } else {
        unlink $_ or warn "unlink $_: $!\n";
      }
    }'

(if your find doesn't support -print0, you can replace with -exec printf '%s\0' {} +).

0

You can do with something like the command as following (tested in environment success).

find ./ -path '*/FOLDER.DUPLICATE.$DRIVEBENDER/*' -type f -execdir sh -c ' 
    if [ "$(stat -c %s -- "$0")" -ge "$(stat -c %s -- "../${0##*/}" || echo 1)" ]; then
        echo mv -v "$0" "../";
    fi 
' '{}' \;

Directories/Files structure before command being executed: please note that the numbers within brackets [...] are files/directories size in byte.

$ tree --du
.
├── [ 4]  1.1
├── [ 8]  2.1 
├── [12]  3.1
├── [55]  FOLDER.DUPLICATE.$DRIVEBENDER 
│   ├── [ 3]  1.1
│   ├── [36]  3.1
│   └── [16]  4.1 
└── [40]  Subfolder 
    ├── [16]  1.2 
    └── [24]  FOLDER.DUPLICATE.$DRIVEBENDER
        ├── [ 8]  2.2
        └── [16]  3.2

         119 bytes used in 3 directories, 9 files

Directories/Files structure after command executed:

$ tree --du
.
├── [ 4]  1.1
├── [ 8]  2.1 
├── [36]  3.1
├── [16]  4.1
├── [ 3]  FOLDER.DUPLICATE.$DRIVEBENDER
│   └── [ 3]  1.1
└── [40]  Subfolder
    ├── [16]  1.2
    ├── [ 8]  2.2
    ├── [16]  3.2
    └── [ 0]  FOLDER.DUPLICATE.$DRIVEBENDER

         107 bytes used in 3 directories, 8 files
  • I tried find ./'FOLDER.DUPLICATE.$DRIVEBENDER'/* -maxdepth 5 -type f -exec sh -c 'if [ $(stat -c %s -- "$0") -g $(stat -c %s -- "../${0##/}") ]; then echo mv "$0" ../' '{}' \;fi` as a) the files in the drivebender folder must be found and b) fi is missing. But still silething is missing: find: Fehlendes Argument für »-exec«. – nico Sep 10 '17 at 18:47
  • So, next try ;-) now find also finds also all entrys for one higher level, but points in the if to the level, it is executed in. So in the example above, if I execute it in Subfolder, it also finds 1.1,3.1 and 4.1 and tries mv 4.1 /.., but does not find 4.1 of course. – nico Sep 10 '17 at 19:34
  • "find: Der Pfad muss vor dem Ausdruck stehen: Subfolder/FOLDER.DUPLICATE.$DRIVEBENDER/file.tobemoved " (Something like: Path must be in front of the expression) But: many thanks for being so patient with me! – nico Sep 10 '17 at 20:47
  • sorry, please check once, I forgot quotes – αғsнιη Sep 11 '17 at 3:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.