Equivalent of Linux `touch` to create an empty file with PowerShell?

180

47

In PowerShell is there an equivalent of touch?

For instance in Linux I can create a new empty file by invoking:

touch filename

On Windows this is pretty awkward -- usually I just open a new instance of notepad and save an empty file.

So is there a programmatic way in PowerShell to do this?

I am not looking to exactly match behaviour of touch, but just to find the simplest possible equivalent for creating empty files.

jsalonen

Posted 2012-11-07T19:28:02.570

Reputation: 7 143

Question was closed 2017-09-22T08:13:15.423

@LưuVĩnhPhúc Clarified the question. I am not looking for feature-complete equivalent of touch, just the matching behaviour for creating empty files. – jsalonen – 2017-09-21T08:04:21.800

A PowerShell-idiomatic implementation that almost has feature parity with the Unix touch utility: https://stackoverflow.com/a/58756360/45375

– mklement0 – 2019-11-07T20:25:36.477

1Thanks. I looked at them, but most of the answer focus on command-prompt. I'd like to have a PowerShell solution that doesn't require me to install new applications. – jsalonen – 2012-11-07T19:33:28.910

Downvoted the question - both features are only a few more lines of code, just implement both, not just half, esp. when the missing half other command is so dangerous. – yzorg – 2014-02-18T00:49:58.250

@yzorg: What do you mean by both features? I was only asking how to create an empty file in PS the way you can do with touch in Linux. – jsalonen – 2014-02-18T09:13:03.793

@jsalonen Use *nix touch on an existing file it will update the last write time without modifying the file, see the links from @amiregelz. This question has a high google ranking for powershell touch, I wanted to alert copy/paste-ers that just this half of it can destroy data, when *nix touch doesn't. See @LittleBoyLost answer that handles when the file already exists. – yzorg – 2014-02-18T14:44:11.693

@jsalonen IOW if you reword the question to 'how to create an empty file in powershell' I'd remove my downvote, but leave *nix touch command out of it. :) – yzorg – 2014-02-18T14:50:32.913

Answers

171

Using the append redirector ">>" resolves the issue where an existing file is deleted:

echo $null >> filename

Yash Agarwal

Posted 2012-11-07T19:28:02.570

Reputation: 2 380

10echo is unnecessary, $null > filename works great. – alirobe – 2015-05-30T12:54:51.740

11This writes 2 bytes of unicode BOM 0xFEFF for me. – mlt – 2016-04-20T19:08:13.893

1Hey, it changes the encoding to UTF-16 LE – Rahil Wazir – 2016-07-04T18:27:20.537

1

@mlt Redirecting to a file in Powershell does write the BOM, so this technique will also write the BOM as well. This question explains how to write a file in PS without the BOM (it is hamhanded I know): http://stackoverflow.com/questions/5596982/using-powershell-to-write-a-file-in-utf-8-without-the-bom

– Bender the Greatest – 2017-01-20T20:07:16.643

6Important note: Many unix tools don't deal with BOM. This includes git for example(even on windows). You're gonna have problems if you use files created in this manner with tools that don't recognize BOMs. e.g. you try to create your .gitignore using this command and wonder why it won't work. BOM is the reason. – martixy – 2017-07-31T22:21:29.460

1Yes - this method actually writes some bytes to the file. Node.js can't deal with those bytes either, creating a syntax error at the start of the file. – TheHansinator – 2017-09-29T20:37:20.603

The answer using New-Item looks like it doesn't set the BOM and the encoding is UTF-8. But lately I've just been running the Linux Subsystem for windows, or just running git bash on windows and using Touch. I launch git bash in a powershell by running & "c:\Program Files\git\bin\bash.exe" – Davos – 2018-03-26T10:35:34.613

Indeed, Windows PowerShell unexpectedly creates a 2-byte file with the UTF-16LE BOM if filename doesn't exist yet. Fortunately, this is a no longer a problem in PowerShell Core, which generally defaults to (BOM-less) UTF-8 and produces a truly empty file. However, unlike the touch utility, this solution doesn't update the last-write timestamp if the file already exists. – mklement0 – 2019-11-05T12:37:36.040

Sorry it doesn't. It gives me something like cmdlet Copy-Item at command pipeline position 1 Supply values for the following parameters: – jsalonen – 2012-11-07T19:37:29.187

just press enter , it will give some error but ignore that , your file will be created. – Yash Agarwal – 2012-11-07T19:38:17.643

Actually you are right, it works. However, it's annoying to work that way if you have to run this many times. – jsalonen – 2012-11-07T19:39:00.107

1Ok. I have modified the ans , now it should do it in one line – Yash Agarwal – 2012-11-07T19:53:27.363

3Also known as 'echo null>filename' from a command prompt, possibly a batch file. Cool to see the PowerShell version of it, thanks! – Mark Allen – 2012-11-07T21:11:43.053

18touch is rather different than this if the file already exists – jk. – 2012-11-07T22:46:12.167

1perhaps echo $null >> filename would be more similar to Unix touch. – Nathan – 2014-05-21T20:11:01.410

113

To create a blank file:

New-Item -ItemType file example.txt

To update the timestamp of a file:

(gci example.txt).LastWriteTime = Get-Date

dangph

Posted 2012-11-07T19:28:02.570

Reputation: 3 478

Does this work for updating the timestamp of a folder? – riahc3 – 2015-07-28T06:31:52.483

1@riahc3, use this: (gi MyFolder).LastWriteTime = Get-Date . You could use that for files too. – dangph – 2015-07-28T11:26:17.623

9Even more pithy: ni example.txt – Nick Cox – 2017-12-21T01:03:46.953

2This method doesn't add the awful BOM bytes and the encoding happily appears to be UTF-8. – Davos – 2018-03-26T10:33:26.967

This should be the accepted answer ans it is a cleaner approach than the accepted one. – The Fool – 2019-11-04T18:35:25.353

5I think this is the best approach! – Jayesh Bhoot – 2013-11-04T15:30:38.020

78

Here is a version that creates a new file if it does not exist or updates the timestamp if it does exist.

Function Touch-File
{
    $file = $args[0]
    if($file -eq $null) {
        throw "No filename supplied"
    }

    if(Test-Path $file)
    {
        (Get-ChildItem $file).LastWriteTime = Get-Date
    }
    else
    {
        echo $null > $file
    }
}

LittleBoyLost

Posted 2012-11-07T19:28:02.570

Reputation: 889

16

Very, very tiny quibble: While Touch-File conforms to the Verb-Noun naming convention of PS, Touch is not an "approved" verb (not that it's a significant requirement: https://msdn.microsoft.com/en-us/library/ms714428.aspx). File is fine, btw. I recommend the names Set-File or Set-LastWriteTime or, my favorite, Update-File. Also, I would recommend Add-Content $file $null instead of echo $null > $file. Finally, set an alias with Set-Alias touch Update-File if you want to keep using the command touch

– Alan McBee – 2017-05-25T23:36:26.527

Suggest adding this as the last line: New-Alias -Name Touch Touch-File – stimpy77 – 2019-10-01T04:33:36.757

Nice, but it's better to use New-Item $file instead of echo $null > $file, because the latter will create a 2-byte file with the UTF-16LE BOM in Windows PowerShell (but no longer in PowerShell Core). – mklement0 – 2019-11-05T12:43:56.657

This has a TOCTTOU race, the file could be created between the check and the action. – poizan42 – 2019-12-27T13:43:57.953

4This is the correct answer for replicating the Unix touch program (albeit with a different name), but the question is oriented to simply creating a new file. – Jamie Schembri – 2014-01-04T11:59:13.687

24

In PowerShell you can create a similar Touch function as such:

function touch {set-content -Path ($args[0]) -Value ($null)} 

Usage:

touch myfile.txt

Source

Ƭᴇcʜιᴇ007

Posted 2012-11-07T19:28:02.570

Reputation: 103 763

1Or the safe version that does not clear out existing file contents

function touch { if((Test-Path -Path ($args[0])) -eq $false) { set-content -Path ($args[0]) -Value ($null) } } – alastairtree – 2018-09-11T16:51:10.123

This is great, thanks! Just what I wanted! Any ideas how I could install this function into the PowerShell so that it loads automatically when I start the shell? – jsalonen – 2012-11-07T19:34:53.620

2Add it to your $profile file. (Run notepad $profile to edit that file.) – Mark Allen – 2012-11-07T21:12:13.597

28This will delete the contents of the file if it exists. – dangph – 2013-01-24T06:31:04.863

14

I prefer

fc > filename

for this task. To work with non-empty files you can use

fc >> filename

fc is simply an alias for Format-Custom. I chose it because it is a short command that does nothing in this context, a noop. It is also nice because if you forget the redirect

fc filename

instead of giving you an error, again it just does nothing. Some other aliases that will work are

ft -> Format-Table
fw -> Format-Wide

Steven Penny

Posted 2012-11-07T19:28:02.570

Reputation: 7 294

11

There are a bunch of worthy answers already, but I quite like the alias of New-Item which is just: ni

You can also forgo the file type declaration (which I assume is implicit when an extension is added), so to create a javascript file with the name of 'x' in my current directory I can simply write:

ni x.js

3 chars quicker than touch!

Jacob E. Dawson

Posted 2012-11-07T19:28:02.570

Reputation: 219

1This is not idempotent ni : The file 'x.js' already exists – Steven Penny – 2017-11-30T12:43:26.943

8

I put together various sources, and wound up with the following, which met my needs. I needed to set the write date of a DLL that was built on a machine in a different timezone:

$update = get-date
Set-ItemProperty -Path $dllPath -Name LastWriteTime -Value $update

Of course, you can also set it for multiple files:

Get-ChildItem *.dll | Set-ItemProperty -Name LastWriteTime -Value $update

John Saunders

Posted 2012-11-07T19:28:02.570

Reputation: 486

Without using a variable? – riahc3 – 2015-07-28T06:33:15.920

1+1 for the most Powershell-ish way to change LastWriteTime on a file (which is what I needed), though the question focused on the new file creation feature of the touch command. – Nathan Hartley – 2013-02-25T15:20:09.467

6

It looks like a bunch of the answers here don't account for file encoding.

I just ran into this problem, for various other reasons, but

echo $null > $file

$null > $file

both produce a UTF-16-LE file, while

New-Item $file -type file

produces a UTF-8 file.

For whatever reason fc > $file and fc >> $file, also seem to produce UTF-8 files.

Out-File $file -encoding utf8

gives you a UTF-8-BOM file, while

Out-File $file -encoding ascii

gives you a UTF-8 file. Other valid (but untested) encodings that Out-File supports are: [[-Encoding] {unknown | string | unicode | bigendianunicode | utf8 | utf7 | utf32 | ascii | default | oem}]. You can also pipe stuff to Out-File to give the file some text data to store, and also an -append flag. For example:

echo $null | Out-File .\stuff.txt -Encoding ascii -Append

this example does not update the timestamp for some reason, but this one does:

echo foo | Out-File .\stuff.txt -Encoding ascii -Append

Although it does have the side effect of appending "foo" to the end of the file.

If you are unsure about what encoding you have, I've found VS-Code has a nifty feature where at the bottom right hand corner it says what the encoding is. I think Notepad++ also has a similar feature.

Garret Hoffman

Posted 2012-11-07T19:28:02.570

Reputation: 61

Set-Content -Path $file -value $null does the job and it does not affect file encoding. Check also ss64 version of touch. – Anton Krouglov – 2017-03-14T15:18:44.630

Yes, in Windows PowerShell $null > $file unfortunately creates a 2-byte file with the UTF-16LE encoding; fortunately, in PowerShell Core you now get a truly empty file, as you do with New-Item in both editions. It is not meaningful to speak of a truly empty file (length of 0 bytes) as having a specific character encoding, such as UTF-8, however. Character encoding is only meaningful with respect to content (which is missing here), and, more specifically, with respect to text content. – mklement0 – 2019-11-05T13:04:48.187

5

Open your profile file:

notepad $profile

Add the following line:

function touch {New-Item "$args" -ItemType File}

Save it and reload your $profile in order to use it straight away. (No need to close and open powershell)

. $profile

To add a new file in the current directory type:

touch testfile.txt

To add a new file inside 'myfolder' directory type:

touch myfolder\testfile.txt

If a file with the same name already exists, it won't be overidden. Instead you'll get an error.

I hope it helps

Bonus tip:

You can make the equivalent of 'mkdir' adding the following line:

function mkdir {New-Item "$args" -ItemType Directory} 

Same use:

mkdir testfolder
mkdir testfolder\testsubfolder

RafaelGP

Posted 2012-11-07T19:28:02.570

Reputation: 179

5

ac file.txt $null

Won't delete the file contents but it won't update the date either.

8DH

Posted 2012-11-07T19:28:02.570

Reputation: 222

3

For the scenario you described (when the file doesn't exist), this is quick and easy:

PS> sc example.txt $null

However, the other common use of touch is to update the file's timestamp. If you try to use my sc example that way, it will erase the contents of the file.

Jay Bazuzi

Posted 2012-11-07T19:28:02.570

Reputation: 3 780

2Thanks! What does sc mean? Edit: figured it out ("Set Content") – jsalonen – 2013-02-27T15:00:41.530

2

The webpage http://xahlee.info/powershell/PowerShell_for_unixer.html suggests:

new-item -type file [filename]

and this does indeed create a new file of size zero.

This doesn't perform the other function of Unix touch, namely to update the timestamp if filename already exists, but the question implies that the user just wants to create a zero-sized file interactively without resorting to Notepad.

ghostarbeiter

Posted 2012-11-07T19:28:02.570

Reputation: 131

2

I used the name "Write-File" because "Touch" isn't an approved PowerShell verb. I still alias it as touch, however.

Touch.psm1

<#
 .Synopsis
  Creates a new file or updates the modified date of an existing file.

 .Parameter Path
  The path of the file to create or update.
#>
Function Write-File {
    [CmdletBinding()]
    Param(
       [Parameter( Mandatory=$True, Position=1 )]
       [string] $Path,
       [switch] $WhatIf,
       [System.Management.Automation.PSCredential] $Credential
    )
    $UseVerbose = $PSCmdlet.MyInvocation.BoundParameters['Verbose'].IsPresent -eq $True
    $UseDebug = $PSCmdlet.MyInvocation.BoundParameters['Debug'].IsPresent -eq $True
    $TimeStamp = Get-Date
    If( -Not [System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters( $Path ) ) {
        New-Item -ItemType:File -Verbose:$UseVerbose -Debug:$UseDebug -WhatIf:$WhatIf -Credential $Credential -Path $Path -ErrorAction SilentlyContinue -Confirm:$False | Out-Null
    }
    Set-ItemProperty -Verbose:$UseVerbose -Debug:$UseDebug -WhatIf:$WhatIf -Credential $Credential -Path $Path -Name LastWriteTime -Value:$TimeStamp -Confirm:$False | Out-Null
}

Set-Alias -Name touch -Value Write-File

Export-ModuleMember -Function Write-File
Export-ModuleMember -Alias touch

Usage:

Import-Module ./Touch.psm1
touch foo.txt

Supports:

  • Paths in other directories
  • Credential for network paths
  • Verbose, Debug, and WhatIf flags
  • wildcards (timestamp update only)

error

Posted 2012-11-07T19:28:02.570

Reputation: 121

The New-Item command has been offered in four previous answers.  You have provided a 20-line wrapper for it.  Can you explain a bit more clearly what advantage your solution has over the earlier ones?  For example, what are these Verbose, Debug, and WhatIf flags, etc? – Scott – 2017-03-23T04:08:53.457

1One important difference between this answer and New-Item is that this updates the timestamp of existing files. – jpaugh – 2018-07-26T15:49:25.783

For some reason, I have to always import the module again and again, this shouldn't happen, right Import-Module ./Touch.psm1 – shirish – 2019-11-04T21:15:13.763

1@shirish You need to import modules every session, yes, unless you put it in a folder in the PSModulePath. (Or add its folder to PSModulePath.) – SilverbackNet – 2020-02-28T20:36:29.087

2

to create an empty file in windows, the fastes way is the following:

fsutil file createnew file.name 0

The zero is filesize in bytes, so this is also useful to create large file (they will not be useful for testing compression since they do not contain actual data and will compress down to pretty much nothing)

Jon Carlstedt

Posted 2012-11-07T19:28:02.570

Reputation: 280