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.
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 tibble
s 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
As you can see, everything worked out great!
Good luck with changing the date of all your files, no matter how many you have !!