¿Equivalente de Linux `touch` para crear un archivo vacío con PowerShell? [duplicar]

167

Esta pregunta ya tiene una respuesta aquí:

En PowerShell, ¿hay un equivalente de touch?

Por ejemplo, en Linux puedo crear un nuevo archivo vacío invocando:

touch filename

En Windows, esto es bastante incómodo: por lo general, solo abro una nueva instancia del bloc de notas y guardo un archivo vacío.

Entonces, ¿hay una forma programática en PowerShell para hacer esto?

No busco igualar exactamente el comportamiento del tacto, sino solo encontrar el equivalente más simple posible para crear archivos vacíos.

jsalonen
fuente
Gracias. Los miré, pero la mayoría de las respuestas se centran en el símbolo del sistema. Me gustaría tener una solución PowerShell que no requiera que instale nuevas aplicaciones.
jsalonen
Votó la pregunta: ambas características son solo unas pocas líneas más de código, solo implemente ambas, no solo la mitad, especialmente. cuando la otra mitad que falta es tan peligrosa.
yzorg
@yzorg: ¿Qué quieres decir con ambas características? Solo preguntaba cómo crear un archivo vacío en PS de la misma forma en que puedes hacerlo touchen Linux.
jsalonen
@jsalonen Use * nix touchen un archivo existente, actualizará el último tiempo de escritura sin modificar el archivo, vea los enlaces de @amiregelz. Esta pregunta tiene una clasificación alta en Google para powershell touch, quería alertar a los copiadores / pegadores de que solo esta mitad puede destruir datos, cuando * nix touch no lo hace. Vea la respuesta @LittleBoyLost que maneja cuando el archivo ya existe.
yzorg

Respuestas:

165

El uso del redireccionador de anexos ">>" resuelve el problema donde se elimina un archivo existente:

echo $null >> filename
Yash Agarwal
fuente
3
También conocido como 'echo null> filename' desde un símbolo del sistema, posiblemente un archivo por lotes. Genial para ver la versión de PowerShell, ¡gracias!
Mark Allen el
16
touch es bastante diferente a esto si el archivo ya existe
jk.
99
echo es innecesario, $null > filenamefunciona muy bien.
alirobe
8
Esto escribe 2 bytes de BOM 0xFEFF unicode para mí.
mlt
44
Nota importante: Muchas herramientas de Unix no manejan BOM. Esto incluye git por ejemplo (incluso en Windows). Tendrá problemas si utiliza archivos creados de esta manera con herramientas que no reconocen listas de materiales. por ejemplo, intentas crear tu .gitignoreusando este comando y te preguntas por qué no funcionará. BOM es la razón.
martixy
96

Para crear un archivo en blanco:

New-Item -ItemType file example.txt

Para actualizar la marca de tiempo de un archivo:

(gci example.txt).LastWriteTime = Get-Date
dangph
fuente
44
¡Creo que este es el mejor enfoque!
Jayesh Bhoot
¿Esto funciona para actualizar la marca de tiempo de una carpeta?
riahc3
1
@ riahc3, utilice la siguiente: (gi MyFolder).LastWriteTime = Get-Date. También puedes usar eso para archivos.
dangph
99
Aún más concisa:ni example.txt
Nick Cox
2
Este método no agrega los horribles bytes BOM y la codificación felizmente parece ser UTF-8.
Davos
75

Aquí hay una versión que crea un nuevo archivo si no existe o actualiza la marca de tiempo si existe.

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
fuente
44
Esta es la respuesta correcta para replicar el programa táctil de Unix (aunque con un nombre diferente), pero la pregunta está orientada a simplemente crear un nuevo archivo.
Jamie Schembri
15
Muy, muy pequeña objeción: aunque Touch-File se ajusta a la convención de nomenclatura verbo-sustantivo de PS, Touchno es un verbo "aprobado" (no es un requisito significativo: msdn.microsoft.com/en-us/library/ms714428. aspx ). Fileestá bien, por cierto. Recomiendo los nombres Set-Fileo Set-LastWriteTime, o, mi favorito, Update-File. Además, recomendaría en Add-Content $file $nulllugar de echo $null > $file. Finalmente, establezca un alias con Set-Alias touch Update-Filesi desea seguir usando el comandotouch
Alan McBee
Sugiera agregar esto como la última línea:New-Alias -Name Touch Touch-File
stimpy77
25

En PowerShell puede crear una función táctil similar como tal:

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

Uso:

touch myfile.txt

Fuente

Ƭᴇcʜιᴇ007
fuente
Esto es genial, gracias! Justo lo que quería! ¿Alguna idea de cómo podría instalar esta función en PowerShell para que se cargue automáticamente cuando inicio el shell?
jsalonen
2
Agréguelo a su archivo $ profile. (Ejecute notepad $ profile para editar ese archivo.)
Mark Allen
25
Esto eliminará el contenido del archivo si existe.
dangph
1
O la versión segura que no borra el contenido de los archivos existentes function touch { if((Test-Path -Path ($args[0])) -eq $false) { set-content -Path ($args[0]) -Value ($null) } }
alastairtree
13

yo prefiero

fc > filename

para esta tarea Para trabajar con archivos no vacíos, puede usar

fc >> filename

fces simplemente un alias para Format-Custom . Lo elegí porque es un comando corto que no hace nada en este contexto, un noop . También es bueno porque si olvidas la redirección

fc filename

en lugar de darte un error, nuevamente no hace nada. Algunos otros alias que funcionarán son

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

Ya hay un montón de respuestas dignas, pero me gusta bastante el alias de New-Item que es solo: ni

También puede renunciar a la declaración de tipo de archivo (que supongo que está implícito cuando se agrega una extensión), por lo que para crear un archivo javascript con el nombre de 'x' en mi directorio actual, simplemente puedo escribir:

ni x.js

¡3 caracteres más rápido que el tacto!

Jacob E. Dawson
fuente
Esto no es idempotenteni : The file 'x.js' already exists
Steven Penny
8

Reuní varias fuentes y terminé con lo siguiente, que satisfizo mis necesidades. Necesitaba establecer la fecha de escritura de una DLL que se creó en una máquina en una zona horaria diferente:

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

Por supuesto, también puede configurarlo para múltiples archivos:

Get-ChildItem *.dll | Set-ItemProperty -Name LastWriteTime -Value $update
John Saunders
fuente
1
+1 para la forma más Powershell-ish de cambiar LastWriteTime en un archivo (que es lo que necesitaba), aunque la pregunta se centró en la nueva función de creación de archivos del comando táctil.
Nathan Hartley
¿Sin usar una variable?
riahc3
5

Abre tu archivo de perfil:

notepad $profile

Agregue la siguiente línea:

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

Guárdelo y vuelva a cargar su perfil $ para usarlo de inmediato. (No es necesario cerrar y abrir powershell)

. $profile

Para agregar un nuevo archivo en el tipo de directorio actual:

touch testfile.txt

Para agregar un nuevo archivo dentro del directorio 'myfolder' escriba:

touch myfolder\testfile.txt

Si ya existe un archivo con el mismo nombre, no se anulará. En cambio, obtendrá un error.

Espero que ayude

Consejo de bonificación:

Puede hacer el equivalente de 'mkdir' agregando la siguiente línea:

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

Mismo uso:

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

No eliminará el contenido del archivo, pero tampoco actualizará la fecha.

8DH
fuente
5

Parece que muchas de las respuestas aquí no tienen en cuenta la codificación de archivos.

Me encontré con este problema, por varias otras razones, pero

echo $null > $file

$null > $file

ambos producen un archivo UTF-16-LE, mientras que

New-Item $file -type file

produce un archivo UTF-8.

Por alguna razón fc > $filey fc >> $file, también parece producir archivos UTF-8.

Out-File $file -encoding utf8

le da un archivo UTF-8-BOM, mientras

Out-File $file -encoding ascii

le da un archivo UTF-8. Otras codificaciones válidas (pero no probadas) que admite Out-File son: [[-Encoding] {unknown | cadena | unicode | bigendianunicode | utf8 | utf7 | utf32 | ascii | por defecto | oem}]. También puede canalizar cosas a Out-File para darle al archivo algunos datos de texto para almacenar, y también un indicador -append. Por ejemplo:

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

este ejemplo no actualiza la marca de tiempo por algún motivo, pero este sí:

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

Aunque tiene el efecto secundario de agregar "foo" al final del archivo.

Si no está seguro de qué codificación tiene, he descubierto que VS-Code tiene una característica ingeniosa en la que en la esquina inferior derecha dice cuál es la codificación. Creo que Notepad ++ también tiene una característica similar.

Garret Hoffman
fuente
Set-Content -Path $file -value $nullhace el trabajo y no afecta la codificación de archivos. Compruebe también la versión de SS64touch .
Anton Krouglov
3

Para el escenario que describió (cuando el archivo no existe), esto es rápido y fácil:

PS> sc example.txt $null

Sin embargo, el otro uso común de touches actualizar la marca de tiempo del archivo. Si intenta usar mi scejemplo de esa manera, borrará el contenido del archivo.

Jay Bazuzi
fuente
1
¡Gracias! Que scsignifica Editar: descifrado ("Establecer contenido")
jsalonen
2

Para crear un archivo vacío en Windows, la forma más rápida es la siguiente:

fsutil file createnew file.name 0

El cero es el tamaño del archivo en bytes, por lo que esto también es útil para crear un archivo grande (no serán útiles para probar la compresión, ya que no contienen datos reales y se comprimirán hasta casi nada)

Jon Carlstedt
fuente
2

La página web http://xahlee.info/powershell/PowerShell_for_unixer.html sugiere:

new-item -type file [filename]

y esto de hecho crea un nuevo archivo de tamaño cero.

Esto no realiza la otra función de Unix touch, es decir, actualizar la marca de tiempo si el nombre de archivo ya existe, pero la pregunta implica que el usuario solo quiere crear un archivo de tamaño cero de forma interactiva sin recurrir al Bloc de notas.

ghostarbeiter
fuente
1

Usé el nombre "Write-File" porque "Touch" no es un verbo aprobado de PowerShell . Todavía lo alias como toque, sin embargo.

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

Apoya:

  • Rutas en otros directorios
  • Credential para rutas de red
  • Verbose, Debugy WhatIfbanderas
  • comodines (solo actualización de marca de tiempo)
error
fuente
El New-Itemcomando se ha ofrecido en cuatro respuestas anteriores. Le proporcionó un contenedor de 20 líneas. ¿Puede explicar un poco más claramente qué ventaja tiene su solución sobre las anteriores? Por ejemplo, ¿cuáles son estos Verbose, Debugy WhatIfbanderas, etc?
Scott
Una diferencia importante entre esta respuesta y New-Itemes que actualiza la marca de tiempo de los archivos existentes.
jpaugh