1

So I would like to copy files to a specific folder based on a certain part in their name. For your overview I put my folder structure below. In the folders D1 and D2 I have multiple files (as example I put names of two files here) and the folders Brightfield and FITC. I would like to move the .TIF files to either the folder Brightfield or FITC dependent on whether the file name has brightfield in its name or FITC (see what I would like).

Current situation:

main Directory
|
|___ Experiment
        ├── D1
           ├── Brightfield
        │  └── FITC
           |__ 20210205_DML_3_4_D1_PM_flow__w1brightfield 100 - CAM_s3_t5.TIF
           |__ 20210205_DML_3_4_D1_PM_flow__w2FITC 100- CAM_s3_t5.TIF
        └── D2
           ├── temperature
           └── weather
           |__ 20210219_DML_3_4_D2_AM_flow__w1brightfield 100 - CAM_s4_t10.TIF
           |__ 20210219_DML_3_4_D2_AM_flow__w2FITC 100- CAM_s4_t10.TIF

What I would like:

main Directory
    |
    |___ Experiment
            ├── D1
               ├── Brightfield
                        |__20210205_DML_3_4_D1_PM_flow__w1brightfield 100 - CAM_s3_t5.TIF
               └── FITC
                        |__ 20210205_DML_3_4_D1_PM_flow__w2FITC 100- CAM_s3_t5.TIF
            ├── D2
               ├── Brightfield
                        |__20210219_DML_3_4_D2_AM_flow__w1brightfield 100 - CAM_s4_t10.TIF
               └── FITC
                        |__20210219_DML_3_4_D2_AM_flow__w2FITC 100- CAM_s4_t10.TIF

In another question asked on stackoverflow I found a code that I thought I could adjust to my situation, but I get an error that says: Error in mapply(FUN = function (path, showWarnings = TRUE, recursive = FALSE, : zero-length inputs cannot be mixed with those of non-zero length. Apparently the list that needs to be formed (in parts) only shows NA. The code that I used is below:

files <- c("20210205_DML_3_4_D0_PM_flow__w1brightfield 100 - CAM_s3_t5.TIF", "20210205_DML_3_4_D0_PM_flow__w2FITC 100- CAM_s3_t5.TIF",
           "20210219_DML_3_4_D1_AM_flow__w1brightfield 100 - CAM_s4_t10.TIF", "20210219_DML_3_4_D1_AM_flow__w2FITC 100- CAM_s4_t10.TIF")
# write some temp (empty) files for copying
for (f in files) writeLines(character(0), f)

parts <- strcapture(".*_(D[01])_*_([brightfield]|[FITC])_.*", files, list(d="", tw=""))
parts
#    d      tw
# 1 D0    Brightfield
# 2 D0    FITC
# 3 D1    Brightfield
# 4 D1    FITC

dirs <- do.call(file.path, parts[complete.cases(parts),])
dirs
# [1] "D0/Brightfield"    "D0/FITC" "D1/Brightfield"    "D1/FITCr"

### pre-condition, only files, no dir-structure
list.files(".", pattern = "D[0-9]", full.names = TRUE, recursive = TRUE)
# [1] "./20210205_DML_3_4_D0_PM_flow__w1brightfield 100 - CAM_s3_t5.TIF"    "./"20210205_DML_3_4_D0_PM_flow__w2FITC 100- CAM_s3_t5.TIF" 

### create dirs, move files
Vectorize(dir.create)(unique(dirs), recursive = TRUE) # creates both D0 and D0/Brightfield, ...
#    D0/Brightfield D0/FITC    D1/Brightfield D1/FITC 
#       TRUE       TRUE       TRUE       TRUE 
file.rename(files, file.path(dirs, files))
# [1] TRUE TRUE TRUE TRUE

### post-condition, files in the correct locations
list.files(".", pattern = "D[0-9]", full.names = TRUE, recursive = TRUE)

Where is it going wrong?

1 Answers1

1

You are doing the parts <- bit wrong, it should be like so:


parts <- strcapture(".*_(D[01])_.*(brightfield|FITC).*", files, list(d="", tw=""))
parts

Output:


> parts
   d          tw
1 D0 brightfield
2 D0        FITC
3 D1 brightfield
4 D1        FITC

There were a couple of errors:

  • you forgot a . in _*_ , correct should be _.*_.
  • Don't put [] around the words brightfield and FITS, that's not how you use [].
  • there aren't underscores around brightfield or FITC in your filenames. So don't put underscores around them in your regular expression.

May I recommend reading up on an introduction article or a tutorial? It does not take much to learn what you need to overcome your problems here.

Sirius
  • 5,224
  • 2
  • 14
  • 21