0

I'm trying to achieve this:

for i in {01..31}
do
    touch -t 202207$i0000 $i-07-2022.md
done

I have 31 .md files named 01-07-2022.md, 02-07-2022.md ... I basically want to change their creation date respectivelly to the date on their name. Is there someone able to tell me what's wrong with my code?

Thank's.

Solution

for i in {01..31}
do
  SetFile -d "$i/01/2022 00:00:00" $i-07-2022.md
done

1 Answer 1

0

The touch command can alter the creation, modification and last access timestamps.

If you are creating a file with touch, then its creation (birth) timestamp and its last modification timestamp can be set with the -t argument provided. Add the -m option to constrain the change to the modification timestamp.

With touch, the creation time cannot be set forward of its current value, but can be decremented into the past.

The ls command is an easy way to see creation (birth) times instead of modification ones. Adding the -U option changes the output from showing the modification data to the creation date.

On macOS, the XCode Command Line Tools (when installed) provide the SetFile utility to manipulate changes in a file's creation timestamp independently of the modification one. For example:

SetFile -d "04/01/2011 01:02:03" myfile

changes the creation timestamp of myfile to the value requested. The modification timestamp remains unaltered, but can be changed with the -m option of SetFile.

SetFile -m "04/01/2022 01:02:03" myfile

Unlike using touch, SetFile can change a file's creation date forward of, or backward from, its current value.

The following script can be used to alter a file's birthtime while retaining its original modification time.

cat chtm.sh
#!/usr/bin/env bash
# Set a file's birth (creation) timestamp while leaving the modification
# (mtime) unaltered.

[ $(uname) = "Darwin" ] || { echo "'$0' must be run on macOS"; exit 1; }
[ $# -ne 2 ] && { printf "Usage: $0 [[CC]YY]MMDDhhmm[.SS] file\n"; exit 1; }

t=$1
f=$2
stat -f "BEFORE: btime: %SB, mtime: %Sm" $f || exit 1

m=$(stat -f "%Sm" -t "%Y%m%d%H%M.%S" $f)  # capture the old mtime
touch  -t $t $f || exit 1                 # update  the btime & mtime
touch -mt $m $f || exit 1                 # restore the old mtime

stat -f "AFTER : btime: %SB, mtime: %Sm" $f
exit

A sample run would be:

touch myfile
./chtm.sh 202212311711.00 myfile
BEFORE: btime: Jan  3 12:19:21 2023, mtime: Jan  3 12:19:21 2023
AFTER : btime: Dec 31 17:11:00 2022, mtime: Jan  3 12:19:21 2023

As for iterating over your files, changing their timestamps based on the file names, do something like:

#!/usr/bin/env bash
for file in *.md
do
    mm=${file:0:2}
    dd=${file:3:2}
    yy=${file:6:4}
    touch -t ${yy}${mm}${dd}0000 ${file}
done

This uses shell parameter expansion features to snip the components you need from the file names found.

Sign up to request clarification or add additional context in comments.

1 Comment

Hello. If I do touch -t 202207010000 myfile then the file creation time changes to 2022/07/01 00:00. Also your solution does not include the loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.