Page 1 of 1

How to truncate a file without updating its timestamp?

Posted: 15 Mar 2024 08:59
by Peter0x44
I have a Makefile, that needs to run under cmd. It contains the following command:
@-touch -r "/tmp/ccprwrlE.ltrans0.o" "/tmp/ccprwrlE.ltrans0.o.tem" > /dev/null 2>&1 && mv "/tmp/ccprwrlE.ltrans0.o.tem" "/tmp/ccprwrlE.ltrans0.o"
To summarize, it copies the timestamp of the ".o" file onto a ".o.tem" file. Afterwards, it renames the ".o.tem" file to be ".o", overwriting it in the process.
The .o.tem file is zero bytes, because it didn't exist prior, and touch created it.
The purpose is to truncate a file, while not modifying its modified date.

My question is, how can I do this using cmd.exe?
I did some searching on my own already. I found this mentioned as a "touch equivalent":
copy /b filename.ext +,,
However, this is going to destroy the timestamp, so it doesn't do the same thing

Is there any equivalent oneliner I can use?

Re: How to truncate a file without updating its timestamp?

Posted: 18 Mar 2024 08:51
by jfl
This is feasible, but very complex to do as a batch script.
It'll be much easier for you to use a Windows port of the Unix touch program.
For example get touch.exe in the GnuWin32 project zip file:
https://sourceforge.net/projects/getgnuwin32/

Re: How to truncate a file without updating its timestamp?

Posted: 21 Mar 2024 18:59
by penpen
There are three different timestamps you might want to change using powershell, so this might help you:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion

set "sourceFile=%~f0"
set "targetFile=stest.txt"

:: Read timestamps into environment variables.
for /f "tokens=1-3" %%a in ('powershell.exe -Command "$src=(Get-Item '%sourceFile%'); $out='' + $src.CreationTime.Ticks + ' ' + ($src.LastWriteTime.Ticks) + ' ' + ($src.LastAccessTime.Ticks); Write-Output $out"') do (
	set "$CreationTime.Ticks=%%~a"
	set "$LastWriteTime.Ticks=%%~b"
	set "$LastAccessTime.Ticks=%%~c"
)

:: Change target file's timestamps.
powershell.exe -Command "$target=(Get-Item '%targetFile%'); $target.CreationTime=$([DateTime]%$CreationTime.Ticks%); $target.LastWriteTime=$([DateTime]%$LastWriteTime.Ticks%); $target.LastAccessTime=$([DateTime]%$LastAccessTime.Ticks%)"



goto :eof
penpen