Home > OS >  Setting the attribute on the creation date of multiple files
Setting the attribute on the creation date of multiple files

Time:10-21

Could someone please help me with the following task. I have a lot of little text files that I "pulled" from a rather unusual control system. When I transfer files, I only receive the content of the files. Unfortunately, I lose all my attributes this way. And I care about the date of creation the most. I managed (using a camera and an OCR program) to bring about the fact that I already have a table with the names of the files and the correct creation dates. As below:

library(tidyverse)
library(lubridate)

df = tibble(
  Name = c("name1.mpf", "name2.mpf", "name3.mpf", "name4.mpf", "name5.mpf"),
  Date = c("12/04/1997", "04/06/1998", "21/08/1998", "22/08/1998", "05/09/1999")
)

df = df %>% mutate(Date = dmy(Date))

Unfortunately, I do not know how to go about setting the creation date of these files in R. I'm a beginner in R. Any suggestions will be appreciated.

I have several hundred files.

CodePudding user response:

Do it like this. First create a project in RStudio (I assume you are using RStudio right now) and then create a new folder in the project directory, simply called Folder. Then put your files there with which you want to set the date. Finally, make a tibble named df with the names and dates of your files.

library(tidyverse)
library(lubridate)
library(fs)

df = tibble(
  fileName = c("name1.mpf", "name2.mpf", "name3.mpf", "name4.mpf", "name5.mpf"),
  fileDate = c("12/04/1997", "04/06/1998", "21/08/1998", "22/08/1998", "05/09/1999")
)

df = df %>% mutate(fileDate = dmy(fileDate))

Now you need two additional functions. Don't worry if you don't understand everything. The functions are proven and tested so they work fine.

fGetInfo = function(file) file %>% file.info() %>% as_tibble()
fsetFileTime = function(data){ 
  data %>% mutate(
    result = case_when(
      is.na(fileDate) ~ "Missing date",
      !file_exists(file) ~ "File dont exist",
      TRUE ~ tryCatch(
        {
          res = "Error"
          if(Sys.setFileTime(file, fileDate)) res = "Date changed"
          res
        }, error = function(msg) res
      )
    )
  )
}

It's time to use the first one to read file attributes.

dffiles = tibble(
  file = dir_ls("Folder", regexp = "."),
  fileName = file %>% path_file(),
  id = 1:length(file)
) %>% 
  mutate(info = map(file, fGetInfo)) %>% 
  unnest(info)
dffiles

output

# A tibble: 7 x 10
  file             fileName     id  size isdir mode      mtime               ctime               atime               exe  
  <fs::path>       <chr>     <int> <dbl> <lgl> <octmode> <dttm>              <dttm>              <dttm>              <chr>
1 Folder/name1.mpf name1.mpf     1   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:19:55 2021-10-20 19:19:55 no   
2 Folder/name2.mpf name2.mpf     2   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:20:30 2021-10-20 19:20:30 no   
3 Folder/name3.mpf name3.mpf     3   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:20:29 2021-10-20 19:20:29 no   
4 Folder/name4.mpf name4.mpf     4   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:20:33 2021-10-20 19:20:33 no   
5 Folder/name5.mpf name5.mpf     5   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:20:32 2021-10-20 19:20:32 no   
6 Folder/name6.mpf name6.mpf     6   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:20:32 2021-10-20 19:20:32 no   
7 Folder/name7.mpf name7.mpf     7   452 FALSE 666       2021-08-03 02:00:00 2021-10-20 19:20:31 2021-10-20 19:20:31 no   

As you can see there are 7 files in my folder (intentionally more than in df) and they all have today's date. Now we need to join tibbles dffiles with df.

dffiles = dffiles %>% left_join(df, by="fileName") 
dffiles%>% 
  select(c(file, fileName, fileDate))

output

# A tibble: 7 x 3
  file             fileName  fileDate  
  <fs::path>       <chr>     <date>    
1 Folder/name1.mpf name1.mpf 2021-08-03
2 Folder/name2.mpf name2.mpf 2021-08-03
3 Folder/name3.mpf name3.mpf 2021-08-03
4 Folder/name4.mpf name4.mpf 2021-08-03
5 Folder/name5.mpf name5.mpf 2021-08-03
6 Folder/name6.mpf name6.mpf NA        
7 Folder/name7.mpf name7.mpf NA  

Finally, there is nothing else to do but set the dates for the appropriate files.

dffiles = dffiles %>% group_by(id) %>% 
  nest(data=c(file, fileDate)) %>% 
  mutate(data = map(data, ~fsetFileTime(.x))) %>% 
  unnest(data) %>% 
  mutate(result = result %>% factor()) 
dffiles %>% 
  select(c(file, fileName, fileDate, result))

output

Adding missing grouping variables: `id`
# A tibble: 7 x 5
# Groups:   id [7]
     id file             fileName  fileDate   result      
  <int> <fs::path>       <chr>     <date>     <fct>       
1     1 Folder/name1.mpf name1.mpf 1997-04-12 Date changed
2     2 Folder/name2.mpf name2.mpf 1998-06-04 Date changed
3     3 Folder/name3.mpf name3.mpf 1998-08-21 Date changed
4     4 Folder/name4.mpf name4.mpf 1998-08-22 Date changed
5     5 Folder/name5.mpf name5.mpf 1999-09-05 Date changed
6     6 Folder/name6.mpf name6.mpf NA         Missing date
7     7 Folder/name7.mpf name7.mpf NA         Missing date

enter image description here

As you can see, everything worked out great!

Good luck with changing the date of all your files, no matter how many you have !!

CodePudding user response:

Please, try the following:

library(tidyverse)
library(lubridate)
library(tidyr)

df %>% 
  mutate(Date = dmy(Date))  %>% 
  mutate(Name = replace(Name, T, str_remove(Name,".mpf"))) %>% 
  unite("Filename",Name, Date) %>% 
  mutate(Filename=paste0(Filename,".mpf"))
  • Related