25

I have a directory on my desktop created using PowerShell, and now I'm trying to create a text file within it.

I did change directory to the new one, and typed touch textfile.txt.

This is the error message I get:

touch : The term 'touch' is not recognized as the name of a cmdlet, function, 
script file, or operable program. Check the spelling of the name, or if a path was 
included, verify that the path is correct and try again.

At line:1 char:1
+ touch file.txt
+ ~~~~~
+ CategoryInfo          : ObjectNotFound: (touch:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException`

Why is it not working? Will I have to use Git Bash all the time?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Antoni Parellada
  • 4,253
  • 6
  • 49
  • 114
  • 3
    If you want to use msys/etc. commands then you need to use git bash or have configured git bash to "pollute" your system `%PATH%` with its bin directories. `touch` isn't a Windows or powershell command. You can't use `Write-Error`, etc. from git bash either. – Etan Reisner Sep 08 '15 at 02:14
  • thanks you for your answer! – Antoni Parellada Sep 08 '15 at 02:30

14 Answers14

31

If you need a command touch in PowerShell you could define a function that does The Right Thing™:

function touch {
  Param(
    [Parameter(Mandatory=$true)]
    [string]$Path
  )

  if (Test-Path -LiteralPath $Path) {
    (Get-Item -Path $Path).LastWriteTime = Get-Date
  } else {
    New-Item -Type File -Path $Path
  }
}

Put the function in your profile so that it's available whenever you launch PowerShell.

Defining touch as an alias (New-Alias -Name touch -Value New-Item) won't work here, because New-Item has a mandatory parameter -Type and you can't include parameters in PowerShell alias definitions.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Is there a race condition if multiple processes do this simultaneously? The Really Right Thing for `touch` is to *atomically* create the file if it doesn't exist. –  Aug 07 '18 at 21:35
  • Well, the code in my answer obviously is not atomic. That would probably require something like trying to create the item, and catching/handling errors at the very least. – Ansgar Wiechers Aug 07 '18 at 23:40
28

If you're using Windows Powershell, the equivalent command to Mac/Unix's touch is: New-Item textfile.txt -type file.

Ryan Chase
  • 2,384
  • 4
  • 24
  • 33
  • 6
    This is not strictly true. `touch` will update a file's timestamp if it exists, without affecting its content. `New-Item` will fail if the file exists. – briantist Jun 29 '16 at 16:49
27

For single file creation in power shell : ni textfile.txt

For multiple files creation at a same time: touch a.txt,b.html,x.js is the linux command
ni a.txt,b.html,x.js is the windows power shell command

M2395
  • 326
  • 3
  • 5
  • 1
    While I understand based on some other answers that this is not exactly the same as touch, this is exactly what I needed for my common use case. – Marc Stober Oct 28 '21 at 12:44
11

As Etan Reisner pointed out, touch is not a command in Windows nor in PowerShell.

If you want to just create a new file quickly (it looks like you're not interested in the use case where you just update the date of an existing file), you can use these:

$null > textfile.txt
$null | sc textfile.txt

Note that the first one will default to Unicode, so your file won't be empty; it will contain 2 bytes, the Unicode BOM.

The second one uses sc (an alias for Set-Content), which defaults to the system's active ANSI code page when used on the FileSystem, which uses no BOM and therefore truly creates an empty file.

If you use an empty string ('' or "" or [String]::Empty) instead of $null you'll end up with a line break also.

mklement0
  • 382,024
  • 64
  • 607
  • 775
briantist
  • 45,546
  • 6
  • 82
  • 127
  • I'm at the prompt `$C:\Users\...\folder> ` If I type `textfile.txt` I get an error message. So far it only works if I type `notepad textfile.txt` and after being prompted by an error message that indicates that there is no such file, I click on the option of creating it. – Antoni Parellada Sep 08 '15 at 03:41
  • 1
    If you don't want the Unicode BOM, just use `Add-Content textfile.txt $null` – Dave C Sep 18 '18 at 15:01
  • 1
    My pleasure, Brian. If you ever feel inspired, you could update the answer with the PowerShell Core perspective (consistent use of BOM-less UTF-8, `sc` no longer being a built-in alias for `Set-Content`). – mklement0 Jul 11 '21 at 21:40
  • 1
    @mklement0 I don't think I'll be able to anytime soon, but you could post a new answer, or edit into your exiting one, and I'd be happy too upvote it and link to it directly from this answer; or you may of course edit this further (though I'd prefer you get the vote credits!). – briantist Jul 11 '21 at 21:50
6

if you are using node, just use this command and it will install touch.

npm install touch-cli -g

Adarsh
  • 61
  • 1
  • 2
4

Here's the touch method with better error handling:

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

    if(Test-Path $file)
    {
        throw "file already exists"
    }
    else
    {
        # echo $null > $file
        New-Item -ItemType File -Name ($file)
    }
}

Add this function to C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1 (create this file if doesn't exist).

Use it like this: touch hey.js

GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
2

cd into the your path where you want the file to be created and then type...

New-item -itemtype file yourfilenamehere.filetype

example

New-item -itemtype file index.js

Gerard
  • 2,200
  • 1
  • 9
  • 6
2

To generalize Ansgar Wiechers' helpful answer, in order to support:

  • multiple files as input, passed as individual arguments (touch file1 file2, as with the Unix touch utility) rather than as an array argument (touch file1, file2), the latter being the PowerShell-idiomatic way to pass multiple values to a single parameter.

  • wildcard patterns as input (only meaningful when targeting existing files, to update their last-write timestamps).

  • -Verbose to get feedback on what actions are performed.

Note:

  • The function only emulates the core functionality of the Unix touch utility:

    • for existing files, it sets the last-write and last-access timestamps to the current point in time,
    • whereas non-existing files are created, with no content.
  • For a more complete emulation that is also more PowerShell-idiomatic, Touch-File, see this answer.

  • The function requires PowerShell version 4 or higher, due to use of the .ForEach() array method (though it could easily be adapted to earlier versions).

function touch {
<#
.SYNOPSIS
Emulates the Unix touch utility's core functionality.
#>
  param(
    [Parameter(Mandatory, ValueFromRemainingArguments)]
    [string[]] $Path
  )

  # For all paths of / resolving to existing files, update the last-write timestamp to now.
  if ($existingFiles = (Get-ChildItem -File $Path -ErrorAction SilentlyContinue -ErrorVariable errs)) {
    Write-Verbose "Updating last-write and last-access timestamps to now: $existingFiles"
    $now = Get-Date
    $existingFiles.ForEach('LastWriteTime', $now)
    $existingFiles.ForEach('LastAccessTime', $now)
  }

  # For all non-existing paths, create empty files.
  if ($nonExistingPaths = $errs.TargetObject) {
    Write-Verbose "Creatng empty file(s): $nonExistingPaths"
    $null = New-Item $nonExistingPaths
  }

}
mklement0
  • 382,024
  • 64
  • 607
  • 775
1

The combination of New-Item with the Name, ItemType, and Path parameters worked for me. In my case, to create a _netrc file for git:

 New-Item -Name _netrc -ItemType File -Path $env:userprofile

References

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
1

How about just use this to create .txt file in PowerShell.

New-Item .txt

Check this website for more information.

Saad Anees
  • 1,255
  • 1
  • 15
  • 32
1

I like to extend the function to create a non-existing folder by default. If you want the traditional behavior providing the option is nice.

function touch {
  param([string]$Name,
    [switch]$Traditional)
  if (-not $Traditional) {
    $names = $Name.Replace("\", "/").Replace("//", "/") -split "/"
    $nameNormalized = $names -join "/"
    $nameNormalized = $nameNormalized.TrimEnd($names[$names.count - 1]).TrimEnd("/")
    if (-not (Test-Path $nameNormalized) -and ($names.count -gt 1)) {      
      New-Item -Path $nameNormalized -ItemType Directory > $null
    }    
  }
  if (-not (Test-Path $Name)) {
    New-Item -Path $Name -ItemType File >$null
  }
  else {
  (Get-Item -Path $Name).LastWriteTime = Get-Date
  }
}

usage:

# will make the folder if it doesn't exist
touch filepath\file.extension
# will throw exception if the folder doesn't exist
touch filepath\file.extension -Traditional
# both will make the file or update the LastWriteTime if the file already exists
Niederee
  • 4,155
  • 25
  • 38
0

If you are using the Window's Power Shell, then the touch command may show an error. Use:

New-Item* filename.filetype 

or

ni* filename.filetype

For example:

New-Item name.txt or ni name.txt
ouflak
  • 2,458
  • 10
  • 44
  • 49
0

In my case, Im just create a alias do command niin myuser_profile.ps1` file.

Set-Alias touch ni

Then I can use this command to create files, for example: touch example.js anotherone.md another.tsx

0

Put this in your Windows pwsh profile and reload

function touch ($myNewFileName) { New-Item $myNewFileName -type file }

touch seems to work in pwsh OOB in MacOS

tedro
  • 51
  • 1
  • 5