Skip to content

Instantly share code, notes, and snippets.

@c0psrul3
Last active May 4, 2023 07:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save c0psrul3/a2b470b1da0c4870a45d to your computer and use it in GitHub Desktop.
Save c0psrul3/a2b470b1da0c4870a45d to your computer and use it in GitHub Desktop.
How to use touch(1)

How to use touch(1) Fast version

Preface:

-- The reader (that's you!) should have a basic understanding of file status, and the attributes a file has (which are not necessarily found in the file itself -- even if hidden).

-- See the stat(2) man page: [[http://man7.org/linux/man-pages/man2/stat.2.html]]

There are 3 kind of "timestamps":

Access - the last time the file was read
Modify - the last time the file was modified (content has been modified)
Change - the last time meta data of the file was changed (e.g. permissions)

To display this information, you can use stat which is part of the coreutils.

stat will show you also some more information like the device, inodes, links, etc.

Remember that this sort of information depends highly on the filesystem and mount options. For example if you mount a partition with the noatime option, no access information will be written.

A utility to change the timestamps would be touch. There are some arguments to decide which timestamp to change (e.g. -a for access time, -m for modification time, etc.) and to influence the parsing of a new given timestamp. See man touch for more details.

touch can become handy in combination with cp -u ("copy only when the SOURCE file is newer than the destination file or when the destination file is missing") or for the creation of empty marker files.


You can change the modification time of a file using the touch command:

touch filename

By default this will set the file's modification time to the current time, but there are a number of flags, such as the -d flag to pick a particular date. So for example, to set a file as being modified two hours before the present, you could use the following:

touch -d "2 hours ago" filename

If you want to modify the file relative to its existing modification time instead, the following should do the trick:

touch -d "$(date -r filename) - 2 hours" filename

If you want to modify a large number of files, you could use the following:

find DIRECTORY -print | while read filename; do
    # do whatever you want with the file
    touch -d "$(date -r "$filename") - 2 hours" "$filename"
done

You can change the arguments to find to select only the files you are interested in. If you only want to update the file modification times relative to the present time, you can simplify this to:

$ find DIRECTORY -exec touch -d "2 hours ago" {} +

This form isn't possible with the file time relative version because it uses the shell to form the arguments to touch.

As far as the creation time goes, most Linux file systems do not keep track of this value. There is a ctime associated with files, but it tracks when the file metadata was last changed. If the file never has its permissions changed, it might happen to hold the creation time, but this is a coincidence. Explicitly changing the file modification time counts as a metadata change, so will also have the side effect of updating the ctime.


In the terminal go to the directory for date-edit. Then type:

find -print | while read filename; do # do whatever you want with the file touch -t 201203101513 "$filename" done

You wil see a ">" after you hit enter, exept for the last time -> "done".

Note: You may want to change "201203101513"

"201203101513" = is the date you want for all the files in this directory.


originally was used to modify the date by minus one month.

Here's the original script:

#!/bin/bash

find specific files

files=$(find . -type f -name '*.JPG')

use newline as file separator (handle spaces in filenames)

IFS=$'\n'

for f in ${files} do

read file modification date using stat as seconds

adjust date backwards (1 month) using date and print in correct format

change file time using touch

touch -t $(date -v -1m -r $(stat -f %m "${f}") +%Y%m%d%H%M.%S) "${f}" done

Here's my modified script that forced the date to the year "2014":

#!/bin/bash

find specific files

#files=$(find . -type f -name '*.JPG')

use newline as file separator (handle spaces in filenames)

IFS=$'\n'

for f in $* do

read file modification date using stat as seconds

adjust date backwards (1 month) using date and print in correct format

change file time using touch

touch -t $(date -v +1y -r $(stat -f %m "${f}") +2014%m%d%H%M.%S) "${f}" done

I now realize I could have done a more generic version:

#!/bin/bash

find specific files

#files=$(find . -type f -name '*.JPG')

use newline as file separator (handle spaces in filenames)

IFS=$'\n'

for f in $* do

read file modification date using stat as seconds

adjust date backwards (1 month) using date and print in correct format

change file time using touch (+1y adds a year "-1y" subtracts a year)

Below line subtracts a year

touch -t $(date -v -1y -r $(stat -f %m "${f}") +%Y%m%d%H%M.%S) "${f}"

Below line adds a year

touch -t $(date -v +1y -r $(stat -f %m "${f}") +%Y%m%d%H%M.%S) "${f}"

done

To use this file you would need to write it and

chmod +x fn

to execute:

./fn files-to-change

fn=your-file-name-that-is-your-command

Example

./fn *.JPG

will change the date by minus one year in the directory where you are.


:: The stat(2) man page describes in more detail when those timestamps are changed. – Cristian Ciupitu Jul 31 '14 at 16:11

:: @Benubird. the access time would be updated upon ls. Probably you're on Linux and the filesystem has been mounted with relatime or noatime options. Try mounting with strictatime (but beware of the performance implications). (BTW, are you planning to undelete your fifo question or have you given up on it altogether? I had done a longish answer to it.) – Stéphane Chazelas Jun 4 at 9:48


The answer of echox is valid but I want to add information regarding file creation time.

Some file systems support an additional entry in the inode regarding the creation time (or birth time). I know that ext4 supports this feature and also JFS and BTRFS.

However most tools and API have not yet been updated to read this extra information. So even-though it could be there, it's not accessible.

For instance on Ubuntu 12.04 LTS I get the following for a file I created today:

$ echo Just another test > /tmp/mytest $ sleep 3 $ touch /tmp/mytest $ sleep 2 $ cat /tmp/mytest > /dev/null $ stat /tmp/mytest [...] Access: 2012-06-05 13:33:44.279774711 +0200 Modify: 2012-06-05 13:33:34.611893317 +0200 Change: 2012-06-05 13:33:34.611893317 +0200 Birth: - $ sudo debugfs -R 'stat /tmp/mytest' /dev/sda1 [...] ctime: 0x4fcdee8e:91e30114 -- Tue Jun 5 13:33:34 2012 atime: 0x4fcdee98:42b417dc -- Tue Jun 5 13:33:44 2012 mtime: 0x4fcdee8e:91e30114 -- Tue Jun 5 13:33:34 2012 crtime: 0x4fcdee46:01258f1c -- Tue Jun 5 13:32:22 2012 [...]

You can see that the newer stat function has a birth field, though the output seems incorrect. And via debugfs we can get the information (crtime as I'm on ext4 file system).


Source URL: [[http://askubuntu.com/questions/62492/how-can-i-change-the-date-modified-created-of-a-file]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment