Equivalente ao Linux `touch` para criar um arquivo vazio com o PowerShell? [duplicado]

167

Esta pergunta já tem uma resposta aqui:

No PowerShell, existe um equivalente a touch?

Por exemplo, no Linux, posso criar um novo arquivo vazio invocando:

touch filename

No Windows, isso é bastante estranho - geralmente eu apenas abro uma nova instância do bloco de notas e salvo um arquivo vazio.

Portanto, existe uma maneira programática no PowerShell de fazer isso?

Não pretendo corresponder exatamente ao comportamento do toque, mas apenas para encontrar o equivalente mais simples possível para a criação de arquivos vazios.

jsalonen
fonte
Obrigado. Eu olhei para eles, mas a maioria das respostas se concentra no prompt de comando. Gostaria de ter uma solução do PowerShell que não exija a instalação de novos aplicativos.
Jsalonen
A questão foi rejeitada - os dois recursos são apenas mais algumas linhas de código, apenas implementam os dois, e não apenas a metade, esp. quando a metade do outro comando que falta é tão perigosa.
yzorg 18/02/14
@yzorg: O que você quer dizer com ambos os recursos? Eu só estava perguntando como criar um arquivo vazio no PS da maneira que você pode fazer touchno Linux.
Jsalonen
@jsalonen Use * nix touchem um arquivo existente; ele atualizará a última hora de gravação sem modificar o arquivo; consulte os links em @amiregelz. Esta pergunta tem uma alta classificação no Google para powershell touch, eu queria alertar os copiadores / coladores que apenas essa metade pode destruir dados, quando o * nix touch não. Consulte a resposta @LittleBoyLost que trata quando o arquivo já existe.
yzorg

Respostas:

164

O uso do redirecionador de acréscimo ">>" resolve o problema em que um arquivo existente é excluído:

echo $null >> filename
Yash Agarwal
fonte
3
Também conhecido como 'eco nulo> nome do arquivo' em um prompt de comando, possivelmente um arquivo em lotes. Legal ver a versão do PowerShell, obrigado!
Mark Allen
16
touch é bem diferente disso se o arquivo já existir
jk.
9
eco é desnecessário, $null > filenamefunciona muito bem.
Alirobe
8
Isso grava 2 bytes de BOM 0xFEFF unicode para mim.
MLT
4
Nota importante: Muitas ferramentas unix não lidam com BOM. Isso inclui o git, por exemplo (mesmo no Windows). Você terá problemas se usar arquivos criados dessa maneira com ferramentas que não reconhecem listas técnicas. por exemplo, você tenta criar seu .gitignoreuso desse comando e se pergunta por que ele não funcionará. BOM é o motivo.
31717 martixy
95

Para criar um arquivo em branco:

New-Item -ItemType file example.txt

Para atualizar o registro de data e hora de um arquivo:

(gci example.txt).LastWriteTime = Get-Date
dangph
fonte
4
Eu acho que essa é a melhor abordagem!
Jayesh Bhoot 4/11
Isso funciona para atualizar o registro de data e hora de uma pasta?
riahc3
11
@ riahc3, use este: (gi MyFolder).LastWriteTime = Get-Date. Você também pode usar isso para arquivos.
dangph
9
Ainda mais conciso:ni example.txt
Nick Cox
2
Esse método não adiciona os terríveis bytes da BOM e a codificação felizmente parece ser UTF-8.
Davos
75

Aqui está uma versão que cria um novo arquivo se ele não existir ou atualiza o registro de data e hora, se existir.

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
fonte
4
Esta é a resposta correta para replicar o programa de toque Unix (embora com um nome diferente), mas a questão é orientada a simplesmente criar um novo arquivo.
Jamie Schembri
14
Quibble muito , muito pequeno: Embora o Touch-File esteja em conformidade com a convenção de nomenclatura Verbo-Substantivo do PS, Touchnão é um verbo "aprovado" (não que seja um requisito significativo: msdn.microsoft.com/en-us/library/ms714428. aspx ). Fileestá bem, aliás. Eu recomendo os nomes Set-Fileou Set-LastWriteTimeou, meu favorito Update-File,. Além disso, eu recomendaria em Add-Content $file $nullvez de echo $null > $file. Por fim, defina um alias com Set-Alias touch Update-Filese você quiser continuar usando o comandotouch
Alan McBee
25

No PowerShell, você pode criar uma função de toque semelhante, como tal:

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

Uso:

touch myfile.txt

Fonte

Ƭᴇcʜιᴇ007
fonte
Isso é ótimo, obrigado! Apenas o que eu queria! Alguma idéia de como eu poderia instalar essa função no PowerShell para que ela seja carregada automaticamente quando inicio o shell?
Jsalonen
2
Adicione-o ao seu arquivo $ profile. (Executar notepad $ profile para editar esse arquivo.)
Mark Allen
25
Isso excluirá o conteúdo do arquivo, se existir.
dangph
11
Ou a versão segura que não limpar o conteúdo do arquivo existentes function touch { if((Test-Path -Path ($args[0])) -eq $false) { set-content -Path ($args[0]) -Value ($null) } }
alastairtree
12

eu prefiro

fc > filename

para esta tarefa. Para trabalhar com arquivos não vazios, você pode usar

fc >> filename

fcé simplesmente um alias para o formato personalizado . Eu o escolhi porque é um comando curto que não faz nada nesse contexto, um noop . Também é legal porque se você esquecer o redirecionamento

fc filename

em vez de lhe dar um erro, novamente não faz nada. Alguns outros apelidos que funcionarão são

ft -> Format-Table
fw -> Format-Wide
Steven Penny
fonte
9

Já existem várias respostas dignas, mas eu gosto bastante do apelido de New-Item, que é apenas: ni

Você também pode renunciar à declaração do tipo de arquivo (que suponho estar implícita quando uma extensão é adicionada), para criar um arquivo javascript com o nome de 'x' no meu diretório atual, basta escrever:

ni x.js

3 caracteres mais rápido que o toque!

Jacob E. Dawson
fonte
Isto não é idempotenteni : The file 'x.js' already exists
Steven Penny
8

Juntei várias fontes e acabei com as seguintes, que atendiam às minhas necessidades. Eu precisava definir a data de gravação de uma DLL que foi criada em uma máquina em um fuso horário diferente:

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

Obviamente, você também pode configurá-lo para vários arquivos:

Get-ChildItem *.dll | Set-ItemProperty -Name LastWriteTime -Value $update
John Saunders
fonte
11
+1 para a maneira mais eficiente de alterar o LastWriteTime em um arquivo (que é o que eu precisava), embora a pergunta tenha se concentrado no novo recurso de criação de arquivo do comando touch.
22613 Nathan Hartley
Sem usar uma variável?
riahc3
5

Abra seu arquivo de perfil:

notepad $profile

Adicione a seguinte linha:

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

Salve-o e recarregue seu perfil $ para usá-lo imediatamente. (Não é necessário fechar e abrir o PowerShell)

. $profile

Para adicionar um novo arquivo no tipo de diretório atual:

touch testfile.txt

Para adicionar um novo arquivo ao diretório 'myfolder', digite:

touch myfolder\testfile.txt

Se um arquivo com o mesmo nome já existir, ele não será substituído. Em vez disso, você receberá um erro.

Espero que ajude

Dica de bônus:

Você pode fazer o equivalente a 'mkdir' adicionando a seguinte linha:

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

Mesmo uso:

mkdir testfolder
mkdir testfolder\testsubfolder
RafaelGP
fonte
5
ac file.txt $null

Não excluirá o conteúdo do arquivo, mas também não atualizará a data.

8DH
fonte
5

Parece que várias respostas aqui não são responsáveis ​​pela codificação de arquivos.

Acabei de encontrar este problema, por vários outros motivos, mas

echo $null > $file

$null > $file

ambos produzem um arquivo UTF-16-LE, enquanto

New-Item $file -type file

produz um arquivo UTF-8.

Por qualquer motivo fc > $filee fc >> $file, também parece produzir arquivos UTF-8.

Out-File $file -encoding utf8

fornece um arquivo UTF-8-BOM, enquanto

Out-File $file -encoding ascii

fornece um arquivo UTF-8. Outras codificações válidas (mas não testadas) suportadas pelo Out-File são: [[-Encoding] {unknown | string | unicode | bigendianunicode | utf8 utf7 utf32 ascii | padrão | oem}]. Você também pode canalizar o material para Out-File para fornecer ao arquivo alguns dados de texto para armazenar e também um sinalizador -append. Por exemplo:

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

este exemplo não atualiza o carimbo de data / hora por algum motivo, mas este faz:

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

Embora tenha o efeito colateral de anexar "foo" ao final do arquivo.

Se você não tiver certeza sobre qual codificação você possui, eu achei o VS-Code com um recurso bacana, onde no canto inferior direito diz qual é a codificação. Eu acho que o Notepad ++ também tem um recurso semelhante.

Garret Hoffman
fonte
Set-Content -Path $file -value $nullfaz o trabalho e não afeta a codificação do arquivo. Verifique também a versão ss64 dotouch .
Anton Krouglov 14/03
3

Para o cenário que você descreveu (quando o arquivo não existe), isso é rápido e fácil:

PS> sc example.txt $null

No entanto, o outro uso comum touché atualizar o registro de data e hora do arquivo. Se você tentar usar meu scexemplo dessa maneira, ele apagará o conteúdo do arquivo.

Jay Bazuzi
fonte
11
Obrigado! O que scsignifica isso ? Edit: descobri ("Set Content")
jsalonen 27/02
2

Para criar um arquivo vazio no Windows, o caminho mais rápido é o seguinte:

fsutil file createnew file.name 0

O zero é o tamanho do arquivo em bytes, portanto, isso também é útil para criar arquivos grandes (eles não serão úteis para testar a compactação, pois não contêm dados reais e serão compactados para praticamente nada)

Jon Carlstedt
fonte
2

A página http://xahlee.info/powershell/PowerShell_for_unixer.html sugere:

new-item -type file [filename]

e isso de fato cria um novo arquivo de tamanho zero.

Isso não executa a outra função do Unix touch, ou seja, atualizar o carimbo de data / hora se o nome do arquivo já existir, mas a pergunta implica que o usuário apenas deseja criar um arquivo de tamanho zero interativamente sem recorrer ao Bloco de Notas.

ghostarbeiter
fonte
1

Usei o nome "Write-File" porque "Touch" não é um verbo aprovado do PowerShell . Eu ainda o apelido como toque, no entanto.

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

Uso:

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

Suporta:

  • Caminhos em outros diretórios
  • Credential para caminhos de rede
  • Verbose, DebugE WhatIfbandeiras
  • curingas (somente atualização de carimbo de data e hora)
erro
fonte
O New-Itemcomando foi oferecido em quatro respostas anteriores. Você forneceu um invólucro de 20 linhas para ele. Você pode explicar um pouco mais claramente que vantagem sua solução tem sobre as anteriores? Por exemplo, quais são esses Verbose, Debuge WhatIfbandeiras, etc?
Scott
Uma diferença importante entre essa resposta e New-Itemé que ela atualiza o carimbo de data / hora dos arquivos existentes.
26418 jpaugh