Equivalente di Linux `touch` per creare un file vuoto con PowerShell? [duplicare]


167

Questa domanda ha già una risposta qui:

In PowerShell esiste un equivalente di touch?

Ad esempio in Linux posso creare un nuovo file vuoto invocando:

touch filename

Su Windows questo è piuttosto imbarazzante - di solito apro una nuova istanza di blocco note e salvo un file vuoto.

Quindi esiste un modo programmatico in PowerShell per farlo?

Non sto cercando di abbinare esattamente il comportamento del tocco, ma solo per trovare l'equivalente più semplice possibile per la creazione di file vuoti.



Grazie. Li ho guardati, ma la maggior parte della risposta si concentra sul prompt dei comandi. Mi piacerebbe avere una soluzione PowerShell che non mi richieda l'installazione di nuove applicazioni.
jsalonen,

Sottovalutato la domanda: entrambe le funzionalità sono solo poche righe di codice, basta implementare entrambe, non solo la metà, esp. quando l'altra metà mancante è così pericolosa.
yzorg,

@yzorg: cosa intendi con entrambe le funzioni? Stavo solo chiedendo come creare un file vuoto in PS come puoi fare con touchLinux.
jsalonen,

@jsalonen Usa * nix touchsu un file esistente aggiornerà l'ultima volta in cui scrivere senza modificare il file, vedi i link da @amiregelz. Questa domanda ha un alto posizionamento su Google powershell touch, volevo avvisare i copia / incolla che solo questa metà può distruggere i dati, quando * nix touch no. Vedi la risposta di @LittleBoyLost che gestisce quando il file esiste già.
yzorg,

Risposte:


165

L'uso del redirector append ">>" risolve il problema in cui un file esistente viene eliminato:

echo $null >> filename

3
Conosciuto anche come 'echo null> nomefile' da un prompt dei comandi, possibilmente un file batch. Fantastico vedere la versione di PowerShell, grazie!
Mark Allen,

16
touch è piuttosto diverso da questo se il file esiste già
jk.

9
l'eco non è necessaria, $null > filenamefunziona benissimo.
alirobe,

8
Questo scrive per me 2 byte di BOM 0xFEFF unicode.
mlt

4
Nota importante: molti strumenti unix non gestiscono la distinta componenti. Questo include git per esempio (anche su Windows). Avrai problemi se usi file creati in questo modo con strumenti che non riconoscono le distinte componenti. ad esempio, provi a creare il tuo .gitignoreusando questo comando e ti chiedi perché non funzionerà. La BOM è la ragione.
martixy

96

Per creare un file vuoto:

New-Item -ItemType file example.txt

Per aggiornare il timestamp di un file:

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

4
Penso che questo sia l'approccio migliore!
Jayesh Bhoot,

Questo funziona per l'aggiornamento del timestamp di una cartella?
riahc3,

1
@ riahc3, utilizzare questo: (gi MyFolder).LastWriteTime = Get-Date. Puoi usarlo anche per i file.
dangph,

9
Ancora più pithy:ni example.txt
Nick Cox il

2
Questo metodo non aggiunge i terribili byte DBA e la codifica sembra felicemente essere UTF-8.
Davos,

75

Ecco una versione che crea un nuovo file se non esiste o aggiorna il timestamp se esiste.

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
    }
}

4
Questa è la risposta corretta per replicare il programma Unix touch (anche se con un nome diverso), ma la domanda è orientata semplicemente alla creazione di un nuovo file.
Jamie Schembri,

15
Cavillo molto , molto piccolo: mentre Touch-File è conforme alla convenzione di denominazione Verb-Noun di PS, Touchnon è un verbo "approvato" (non che sia un requisito significativo: msdn.microsoft.com/en-us/library/ms714428. aspx ). Fileva bene, a proposito. Vi consiglio i nomi Set-Fileo le Set-LastWriteTimeo, il mio preferito, Update-File. Inoltre, consiglierei Add-Content $file $nullinvece di echo $null > $file. Infine, imposta un alias con Set-Alias touch Update-Filese desideri continuare a utilizzare il comandotouch
Alan McBee,

Suggerisci di aggiungere questo come ultima riga:New-Alias -Name Touch Touch-File
stimpy77

25

In PowerShell puoi creare una funzione Touch simile come tale:

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

Uso:

touch myfile.txt

fonte


Questo è fantastico, grazie! Proprio quello che volevo! Qualche idea su come potrei installare questa funzione in PowerShell in modo che si carichi automaticamente quando avvio la shell?
jsalonen,

2
Aggiungilo al tuo file $ profile. (Esegui il blocco note $ profile per modificare quel file.)
Mark Allen

25
Ciò eliminerà il contenuto del file se esiste.
dangph

1
O la versione sicura che non cancella il contenuto del file esistente function touch { if((Test-Path -Path ($args[0])) -eq $false) { set-content -Path ($args[0]) -Value ($null) } }
alastairtree,

13

preferisco

fc > filename

per questo compito. Per lavorare con file non vuoti puoi usare

fc >> filename

fcè semplicemente un alias per Format-Custom . L'ho scelto perché è un comando breve che non fa nulla in questo contesto, un noop . È anche bello perché se si dimentica il reindirizzamento

fc filename

invece di darti un errore, ancora una volta non fa nulla. Alcuni altri alias che funzioneranno sono

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

9

Ci sono già un sacco di risposte meritevoli, ma mi piace abbastanza l'alias di New-Item che è proprio: ni

Puoi anche rinunciare alla dichiarazione del tipo di file (che presumo sia implicita quando viene aggiunta un'estensione), quindi per creare un file javascript con il nome di 'x' nella mia directory corrente posso semplicemente scrivere:

ni x.js

3 caratteri più veloci del tocco!


Questo non è idempotenteni : The file 'x.js' already exists
Steven Penny,

8

Ho messo insieme varie fonti e ho concluso con le seguenti affermazioni, che hanno soddisfatto i miei bisogni. Avevo bisogno di impostare la data di scrittura di una DLL costruita su un computer in un fuso orario diverso:

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

Naturalmente, puoi anche impostarlo per più file:

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

1
+1 per il modo più Powershell-ish per cambiare LastWriteTime su un file (che è quello di cui avevo bisogno), sebbene la domanda si concentrasse sulla nuova funzione di creazione di file del comando touch.
Nathan Hartley,

Senza usare una variabile?
riahc3,

5

Apri il tuo file di profilo:

notepad $profile

Aggiungi la seguente riga:

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

Salvalo e ricarica il tuo profilo $ per usarlo subito. (Non è necessario chiudere e aprire PowerShell)

. $profile

Per aggiungere un nuovo file nel tipo di directory corrente:

touch testfile.txt

Per aggiungere un nuovo file all'interno del tipo di directory 'myfolder':

touch myfolder\testfile.txt

Se esiste già un file con lo stesso nome, non verrà sovrascritto. Invece otterrai un errore.

spero possa essere d'aiuto

Suggerimento bonus:

Puoi fare l'equivalente di 'mkdir' aggiungendo la seguente riga:

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

Stesso uso:

mkdir testfolder
mkdir testfolder\testsubfolder

5
ac file.txt $null

Non eliminerà il contenuto del file ma non aggiornerà nemmeno la data.


5

Sembra che un sacco di risposte qui non tengono conto della codifica dei file.

Ho appena incontrato questo problema, per vari altri motivi, ma

echo $null > $file

$null > $file

entrambi producono un file UTF-16-LE, mentre

New-Item $file -type file

produce un file UTF-8.

Per qualsiasi motivo fc > $filee fc >> $file, sembrano anche produrre file UTF-8.

Out-File $file -encoding utf8

ti dà un file UTF-8-BOM, mentre

Out-File $file -encoding ascii

ti dà un file UTF-8. Altre codifiche valide (ma non testate) supportate da Out-File sono: [[-Codifica] {sconosciuto | stringa | unicode | bigendianunicode | utf8 | utf7 | utf32 | ascii | impostazione predefinita | oem}]. Puoi anche reindirizzare gli elementi in Out-File per fornire al file alcuni dati di testo da archiviare e anche un flag -append. Per esempio:

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

questo esempio non aggiorna il timestamp per qualche motivo, ma questo fa:

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

Anche se ha l'effetto collaterale di aggiungere "pippo" alla fine del file.

Se non sei sicuro di quale codifica hai, ho scoperto che VS-Code ha una caratteristica elegante in cui nell'angolo in basso a destra dice qual è la codifica. Penso che Notepad ++ abbia anche una funzione simile.


Set-Content -Path $file -value $nullfa il lavoro e non influisce sulla codifica dei file. Controlla anche la versione ss64 ditouch .
Anton Krouglov,

3

Per lo scenario che hai descritto (quando il file non esiste), questo è semplice e veloce:

PS> sc example.txt $null

Tuttavia, l'altro uso comune di touchè aggiornare la data / ora del file. Se provi a usare il mio scesempio in questo modo, cancellerà il contenuto del file.


1
Grazie! Cosa scsignifica? Modifica: capito ("Imposta contenuto")
jsalonen,

2

per creare un file vuoto in Windows, il modo rapido è il seguente:

fsutil file createnew file.name 0

Lo zero ha dimensioni file in byte, quindi è utile anche per creare file di grandi dimensioni (non saranno utili per testare la compressione poiché non contengono dati effettivi e si comprimeranno praticamente in nulla)


2

La pagina web http://xahlee.info/powershell/PowerShell_for_unixer.html suggerisce:

new-item -type file [filename]

e questo crea davvero un nuovo file di dimensioni zero.

Questo non svolge l'altra funzione di Unix touch, vale a dire aggiornare il timestamp se il nome file esiste già, ma la domanda implica che l'utente vuole solo creare un file di dimensioni zero in modo interattivo senza ricorrere a Blocco note.


1

Ho usato il nome "Write-File" perché "Touch" non è un verbo PowerShell approvato . Comunque lo alias ancora come tocco.

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

Supporta:

  • Percorsi in altre directory
  • Credential per i percorsi di rete
  • Verbose, Debuge WhatIfflag
  • caratteri jolly (solo aggiornamento data / ora)

Il New-Itemcomando è stato offerto in quattro precedenti risposte. Hai fornito un wrapper a 20 righe per questo. Puoi spiegarci un po 'più chiaramente quale vantaggio ha la tua soluzione rispetto alle precedenti? Ad esempio, quali sono questi Verbose, Debuge WhatIfbandiere, ecc?
Scott,

Una differenza importante tra questa risposta e New-Itemquella è che questo aggiorna il timestamp dei file esistenti.
jpaugh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.