Odpowiednik linuksowego „touch”, aby utworzyć pusty plik za pomocą PowerShell? [duplikować]

167

To pytanie ma już odpowiedź tutaj:

Czy w PowerShell jest odpowiednik touch?

Na przykład w systemie Linux mogę utworzyć nowy pusty plik, wywołując:

touch filename

W systemie Windows jest to dość niezręczne - zwykle po prostu otwieram nowe wystąpienie notatnika i zapisuję pusty plik.

Czy jest więc programowy sposób w PowerShell, aby to zrobić?

Nie chcę dokładnie dopasować zachowania dotyku, ale po prostu znaleźć najprostszy możliwy odpowiednik do tworzenia pustych plików.

jsalonen
źródło
Dzięki. Patrzyłem na nie, ale większość odpowiedzi skupiała się na wierszu poleceń. Chciałbym mieć rozwiązanie PowerShell, które nie wymaga ode mnie instalowania nowych aplikacji.
jsalonen,
Przejrzałem pytanie - obie funkcje to tylko kilka kolejnych linii kodu, wystarczy zaimplementować obie, a nie tylko połowę, szczególnie. gdy brakująca połowa drugiej komendy jest tak niebezpieczna.
yzorg
@yzorg: Co rozumiesz przez obie funkcje? Pytałem tylko, jak utworzyć pusty plik w PS, tak jak można to zrobić touchw Linuksie.
jsalonen
@jsalonen Użyj * nix touchna istniejącym pliku, zaktualizuje on ostatni czas zapisu bez modyfikacji pliku, zobacz linki z @amiregelz. To pytanie ma wysoki ranking Google powershell touch, chciałem ostrzec kopiujących / wklejających, że tylko ta połowa może zniszczyć dane, gdy * nix touch nie. Zobacz odpowiedź @LittleBoyLost, która obsługuje, gdy plik już istnieje.
yzorg

Odpowiedzi:

164

Użycie dołączającego readresatora „>>” rozwiązuje problem polegający na usunięciu istniejącego pliku:

echo $null >> filename
Yash Agarwal
źródło
3
Znany również jako „echo null> nazwa pliku” w wierszu polecenia, prawdopodobnie plik wsadowy. Fajnie jest zobaczyć wersję PowerShell, dzięki!
Mark Allen
16
touch jest inny niż ten, jeśli plik już istnieje
jk.
9
echo jest niepotrzebne, $null > filenamedziała świetnie.
alirobe
8
To zapisuje dla mnie 2 bajty BOM 0xFEFF w Unicode.
mlt
4
Ważna uwaga: wiele narzędzi uniksowych nie obsługuje BOM. Obejmuje to na przykład git (nawet w systemie Windows). Będziesz mieć problemy, jeśli użyjesz plików utworzonych w ten sposób z narzędziami, które nie rozpoznają BOM. np. próbujesz stworzyć swoje .gitignoreza pomocą tego polecenia i zastanawiasz się, dlaczego to nie zadziała. BOM jest powodem.
martixy
96

Aby utworzyć pusty plik:

New-Item -ItemType file example.txt

Aby zaktualizować znacznik czasu pliku:

(gci example.txt).LastWriteTime = Get-Date
chrzanić
źródło
4
Myślę, że to najlepsze podejście!
Jayesh Bhoot,
Czy to działa w przypadku aktualizacji znacznika czasu folderu?
riahc3
1
@ riahc3, użyj tego: (gi MyFolder).LastWriteTime = Get-Date. Możesz użyć tego również do plików.
dangph
9
Jeszcze bardziej zwięzłe:ni example.txt
Nick Cox,
2
Ta metoda nie dodaje okropnych bajtów BOM, a kodowanie na szczęście wygląda na UTF-8.
Davos
75

Oto wersja, która tworzy nowy plik, jeśli nie istnieje, lub aktualizuje znacznik czasu, jeśli istnieje.

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
źródło
4
To poprawna odpowiedź na replikację programu dotykowego Unix (aczkolwiek o innej nazwie), ale pytanie ma na celu po prostu utworzenie nowego pliku.
Jamie Schembri
14
Bardzo, bardzo drobna kłótnia: podczas gdy Touch-File jest zgodny z konwencją nazewnictwa czasownik-rzeczownik PS, Touchnie jest to czasownik „zatwierdzony” (nie jest to znaczący wymóg: msdn.microsoft.com/en-us/library/ms714428. aspx ). Filejest dobrze, przy okazji. Polecam nazwiska Set-Filelub Set-LastWriteTimelub, mój ulubiony, Update-File. Również poleciłbym Add-Content $file $nullzamiast echo $null > $file. Na koniec ustaw alias, Set-Alias touch Update-Filejeśli chcesz nadal używać poleceniatouch
Alan McBee
Zaproponuj dodanie tego jako ostatniego wiersza:New-Alias -Name Touch Touch-File
stimpy77
25

W PowerShell możesz utworzyć podobną funkcję dotykową jako taką:

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

Stosowanie:

touch myfile.txt

Źródło

Ƭᴇcʜιᴇ007
źródło
To jest wielki, dzięki! Właśnie tego chciałem! Wszelkie pomysły, w jaki sposób mogę zainstalować tę funkcję w programie PowerShell, aby ładowała się automatycznie po uruchomieniu powłoki?
jsalonen
2
Dodaj go do pliku profilu $. (Uruchom notatnik $ profil, aby edytować ten plik.)
Mark Allen
25
Spowoduje to usunięcie zawartości pliku, jeśli istnieje.
dangph
1
Lub bezpieczna wersja, która nie usuwa istniejącej zawartości pliku function touch { if((Test-Path -Path ($args[0])) -eq $false) { set-content -Path ($args[0]) -Value ($null) } }
alastairtree
13

wolę

fc > filename

do tego zadania. Do pracy z niepustymi plikami możesz użyć

fc >> filename

fcjest po prostu aliasem formatu niestandardowego . Wybrałem go, ponieważ jest to krótkie polecenie, które nic nie robi w tym kontekście, noop . Jest to również miłe, ponieważ jeśli zapomnisz o przekierowaniu

fc filename

zamiast dawać ci błąd, znowu nic nie robi. Inne aliasy, które będą działać, to

ft -> Format-Table
fw -> Format-Wide
Steven Penny
źródło
9

Istnieje już wiele godnych odpowiedzi, ale podoba mi się alias New-Item, który jest po prostu: ni

Możesz także zrezygnować z deklaracji typu pliku (który, jak zakładam, jest domyślny po dodaniu rozszerzenia), więc aby utworzyć plik javascript o nazwie „x” w moim bieżącym katalogu, mogę po prostu napisać:

ni x.js

3 znaki szybciej niż dotyk!

Jacob E. Dawson
źródło
To nie jest idempotentneni : The file 'x.js' already exists
Steven Penny
8

Zebrałem różne źródła i podsumowałem następujące, które spełniły moje potrzeby. Musiałem ustawić datę zapisu biblioteki DLL, która została zbudowana na komputerze w innej strefie czasowej:

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

Oczywiście można również ustawić dla wielu plików:

Get-ChildItem *.dll | Set-ItemProperty -Name LastWriteTime -Value $update
John Saunders
źródło
1
+1 za najbardziej zaawansowany sposób Powershell na zmianę LastWriteTime na pliku (to jest to, czego potrzebowałem), chociaż pytanie skupiło się na nowej funkcji tworzenia pliku polecenia dotykowego.
Nathan Hartley,
Bez użycia zmiennej?
riahc3
5

Otwórz plik profilu:

notepad $profile

Dodaj następujący wiersz:

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

Zapisz go i ponownie załaduj swój profil $, aby móc z niego natychmiast korzystać. (Nie trzeba zamykać i otwierać programu PowerShell)

. $profile

Aby dodać nowy plik do bieżącego katalogu:

touch testfile.txt

Aby dodać nowy plik do katalogu „myfolder”, wpisz:

touch myfolder\testfile.txt

Jeśli plik o tej samej nazwie już istnieje, nie zostanie on zastąpiony. Zamiast tego pojawi się błąd.

Mam nadzieję, że to pomoże

Wskazówka bonusowa:

Możesz zrobić odpowiednik „mkdir”, dodając następujący wiersz:

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

To samo zastosowanie:

mkdir testfolder
mkdir testfolder\testsubfolder
RafaelGP
źródło
5
ac file.txt $null

Nie usunie zawartości pliku, ale też nie zaktualizuje daty.

8DH
źródło
5

Wygląda na to, że garść odpowiedzi tutaj nie uwzględnia kodowania plików.

Właśnie zetknąłem się z tym problemem z różnych innych powodów, ale

echo $null > $file

$null > $file

oba tworzą plik UTF-16-LE, podczas gdy

New-Item $file -type file

tworzy plik UTF-8.

Z jakiegokolwiek powodu fc > $filei fc >> $filewydaje się również produkować pliki UTF-8.

Out-File $file -encoding utf8

daje ci plik UTF-8-BOM, podczas gdy

Out-File $file -encoding ascii

daje plik UTF-8. Inne prawidłowe (ale nieprzetestowane) kodowania obsługiwane przez Out-File to: [[-Encoding] {nieznany | ciąg | Unicode | bigendianunicode | utf8 | utf7 | utf32 | ascii | domyślne | oem}]. Możesz także przesyłać elementy do pliku wyjściowego, aby przekazać plikowi dane tekstowe do przechowywania, a także flagę -append. Na przykład:

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

ten przykład z jakiegoś powodu nie aktualizuje znacznika czasu, ale ten:

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

Chociaż ma efekt uboczny, dodając „foo” na końcu pliku.

Jeśli nie masz pewności, jakie masz kodowanie, odkryłem, że VS-Code ma ciekawą funkcję, w której w prawym dolnym rogu jest napisane, co to jest kodowanie. Myślę, że Notepad ++ ma również podobną funkcję.

Garret Hoffman
źródło
Set-Content -Path $file -value $nullwykonuje zadanie i nie wpływa na kodowanie plików. Sprawdź także wersję ss64touch .
Anton Krouglov
3

W opisanym scenariuszu (gdy plik nie istnieje) jest to szybkie i łatwe:

PS> sc example.txt $null

Jednak innym powszechnym zastosowaniem touchjest aktualizacja sygnatury czasowej pliku. Jeśli spróbujesz użyć mojego scprzykładu w ten sposób, spowoduje to usunięcie zawartości pliku.

Jay Bazuzi
źródło
1
Dzięki! Co scznaczy Edycja: wymyśliłem to („Ustaw zawartość”)
jsalonen
2

aby utworzyć pusty plik w systemie Windows, najszybszy sposób jest następujący:

fsutil file createnew file.name 0

Zerem jest rozmiar pliku w bajtach, więc jest to również przydatne do tworzenia dużych plików (nie będą one przydatne do testowania kompresji, ponieważ nie zawierają rzeczywistych danych i spakują się prawie do zera)

Jon Carlstedt
źródło
2

Strona http://xahlee.info/powershell/PowerShell_for_unixer.html sugeruje:

new-item -type file [filename]

i to rzeczywiście tworzy nowy plik o rozmiarze zero.

Nie wykonuje to innej funkcji Uniksa touch, mianowicie aktualizuje znacznik czasu, jeśli nazwa pliku już istnieje, ale pytanie sugeruje, że użytkownik chce tylko interaktywnie utworzyć plik o zerowej wielkości bez uciekania się do Notatnika.

ghostarbeiter
źródło
1

Użyłem nazwy „Write-File”, ponieważ „Touch” nie jest zatwierdzonym czasownikiem PowerShell . Nadal jednak nazywam to dotykiem.

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

Stosowanie:

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

Obsługuje:

  • Ścieżki w innych katalogach
  • Credential dla ścieżek sieciowych
  • Verbose, Debugi WhatIfflagi
  • symbole wieloznaczne (tylko aktualizacja sygnatury czasowej)
błąd
źródło
New-ItemKomenda została zaoferowana w czterech poprzednich odpowiedzi. Podałeś mu 20-liniowe opakowanie. Czy możesz wyjaśnić nieco jaśniej, jaką przewagę ma twoje rozwiązanie nad wcześniejszymi? Na przykład, co to są te Verbose, Debugoraz WhatIfflagi, itp?
Scott
Jedną ważną różnicą między tą odpowiedzią a tą New-Itemjest to, że aktualizuje znacznik czasu istniejących plików.
jpaugh