Эквивалент Linux `touch` для создания пустого файла с PowerShell? [Дубликат]

167

На этот вопрос уже есть ответ здесь:

В PowerShell есть эквивалент touch?

Например, в Linux я могу создать новый пустой файл, вызвав:

touch filename

В Windows это довольно неудобно - обычно я просто открываю новый экземпляр блокнота и сохраняю пустой файл.

Так есть ли в PowerShell программный способ сделать это?

Я не ищу точное соответствие поведению касания, но просто чтобы найти самый простой из возможных эквивалентов для создания пустых файлов.

jsalonen
источник
Благодарю. Я посмотрел на них, но большая часть ответа сосредоточена на командной строке. Я хотел бы иметь решение PowerShell, которое не требует от меня установки новых приложений.
jsalonen
Снизил вопрос - обе функции - это всего лишь несколько строк кода, просто реализуйте обе, а не только половину, esp. когда недостающая половина другой команды настолько опасна.
yzorg
@yzorg: Что вы подразумеваете под обеими функциями? Я только спрашивал, как создать пустой файл в PS, как это можно сделать touchв Linux.
jsalonen
@jsalonen Используйте * nix touchдля существующего файла, он обновит время последней записи без изменения файла, см. ссылки на @amiregelz. Этот вопрос имеет высокий рейтинг в Google powershell touch, я хотел предупредить копировщиков о том, что только эта половина может уничтожить данные, а * nix touch - нет. Смотрите ответ @LittleBoyLost, который обрабатывает, когда файл уже существует.
yzorg

Ответы:

165

Использование перенаправителя добавления «>>» решает проблему удаления существующего файла:

echo $null >> filename
Яш Агарвал
источник
3
Также известный как 'echo null> filename' из командной строки, возможно, командный файл. Здорово видеть версию PowerShell, спасибо!
Марк Аллен
16
touch немного отличается от этого, если файл уже существует
jk.
9
эхо не нужно, $null > filenameпрекрасно работает.
Алироби
8
Это пишет 2 байта Unicode BOM 0xFEFF для меня.
млт
4
Важное примечание: многие инструменты Unix не имеют отношения к спецификации. Это включает в себя мерзавец, например (даже на окнах). У вас будут проблемы, если вы будете использовать файлы, созданные таким образом, с инструментами, которые не распознают спецификации. Например, вы пытаетесь создать свою .gitignoreкоманду с помощью этой команды и удивляетесь, почему она не работает. BOM является причиной.
martixy
96

Чтобы создать пустой файл:

New-Item -ItemType file example.txt

Чтобы обновить метку времени файла:

(gci example.txt).LastWriteTime = Get-Date
dangph
источник
4
Я думаю, что это лучший подход!
Джаеш Бхут
Это работает для обновления отметки времени папки?
riahc3
1
@ riahc3, используйте это: (gi MyFolder).LastWriteTime = Get-Date. Вы можете использовать это для файлов тоже.
dangph
9
Еще более содержательно:ni example.txt
Ник Кокс
2
Этот метод не добавляет ужасные байты BOM, и кодировка, похоже, выглядит как UTF-8.
Давос,
75

Вот версия, которая создает новый файл, если он не существует, или обновляет отметку времени, если он существует.

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
источник
4
Это правильный ответ для репликации сенсорной программы Unix (хотя и с другим именем), но вопрос ориентирован на простое создание нового файла.
Джейми Шембри
15
Очень, очень крошечное замечание: хотя Touch-File соответствует соглашению об именовании Verb-Noun PS, Touchэто не «одобренный» глагол (не то, чтобы это существенное требование: msdn.microsoft.com/en-us/library/ms714428. aspx ). Fileхорошо, кстати. Я рекомендую имена Set-Fileили Set-LastWriteTimeили, мой любимый, Update-File. Кроме того, я бы порекомендовал Add-Content $file $nullвместо echo $null > $file. Наконец, установите псевдоним с, Set-Alias touch Update-Fileесли вы хотите продолжать использовать командуtouch
Alan McBee
Предложите добавить это в качестве последней строки:New-Alias -Name Touch Touch-File
stimpy77
25

В PowerShell вы можете создать аналогичную функцию Touch как таковую:

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

Использование:

touch myfile.txt

Источник

Ƭᴇcʜιᴇ007
источник
Это здорово, спасибо! Как раз то, что я хотел! Любые идеи, как я мог бы установить эту функцию в PowerShell, чтобы она автоматически загружалась при запуске оболочки?
jsalonen
2
Добавьте его в свой файл профиля $. (Запустите notepad $ profile, чтобы редактировать этот файл.)
Марк Аллен
25
Это удалит содержимое файла, если он существует.
dangph
1
Или безопасная версия, которая не очищает существующее содержимое файла function touch { if((Test-Path -Path ($args[0])) -eq $false) { set-content -Path ($args[0]) -Value ($null) } }
alastairtree
13

я предпочитаю

fc > filename

для этой задачи. Для работы с непустыми файлами вы можете использовать

fc >> filename

fcэто просто псевдоним для Format-Custom . Я выбрал его, потому что это короткая команда, которая ничего не делает в этом контексте, ноуп . Это также приятно, потому что если вы забудете о перенаправлении

fc filename

вместо того, чтобы дать вам ошибку, опять же это просто ничего не делает. Некоторые другие псевдонимы, которые будут работать

ft -> Format-Table
fw -> Format-Wide
Стивен Пенни
источник
9

Уже есть куча достойных ответов, но мне очень нравится псевдоним New-Item, который просто: ni

Вы также можете отказаться от объявления типа файла (которое, как я полагаю, подразумевается при добавлении расширения), поэтому для создания файла javascript с именем «x» в моем текущем каталоге я могу просто написать:

ni x.js

3 символа быстрее, чем прикосновение!

Джейкоб Э. Доусон
источник
Это не идемпотентni : The file 'x.js' already exists
Стивен Пенни
8

Я собрал различные источники и нашел следующее, которое отвечало моим потребностям. Мне нужно было установить дату записи DLL, которая была собрана на машине в другом часовом поясе:

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

Конечно, вы также можете установить его для нескольких файлов:

Get-ChildItem *.dll | Set-ItemProperty -Name LastWriteTime -Value $update
Джон Сондерс
источник
1
+1 для наиболее эффективного способа изменения свойства LastWriteTime для файла (что мне было нужно) в Powershell-ih, хотя вопрос был сосредоточен на новой функции создания файла в сенсорной команде.
Натан Хартли
Без использования переменной?
riahc3
5

Откройте файл своего профиля:

notepad $profile

Добавьте следующую строку:

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

Сохраните его и перезагрузите свой профиль $, чтобы сразу его использовать. (Не нужно закрывать и открывать powershell)

. $profile

Чтобы добавить новый файл в текущий каталог, введите:

touch testfile.txt

Чтобы добавить новый файл в директорию myfolder, введите:

touch myfolder\testfile.txt

Если файл с таким именем уже существует, он не будет переопределен. Вместо этого вы получите ошибку.

Я надеюсь, что это помогает

Бонусный совет:

Вы можете сделать эквивалент mkdir, добавив следующую строку:

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

То же использование:

mkdir testfolder
mkdir testfolder\testsubfolder
RafaelGP
источник
5
ac file.txt $null

Не удалит содержимое файла, но также не обновит дату.

8DH
источник
5

Похоже, что куча ответов здесь не учитывает кодировку файлов.

Я просто столкнулся с этой проблемой по разным причинам, но

echo $null > $file

$null > $file

оба производят файл UTF-16-LE, в то время как

New-Item $file -type file

создает файл UTF-8

По какой-то причине fc > $fileи fc >> $file, кажется, также производить файлы UTF-8.

Out-File $file -encoding utf8

дает вам файл UTF-8-BOM, в то время как

Out-File $file -encoding ascii

дает вам файл UTF-8. Другие допустимые (но не проверенные) кодировки, которые поддерживает Out-File: [[-Encoding] {unknown | строка | Юникод | bigendianunicode | utf8 | utf7 | utf32 | ASCII | по умолчанию | ОЙ}]. Вы также можете передать данные в Out-File, чтобы дать файлу некоторые текстовые данные для хранения, а также флаг -append. Например:

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

этот пример не обновляет временную метку по какой-то причине, но этот:

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

Хотя у него есть побочный эффект добавления «foo» в конец файла.

Если вы не уверены в том, какая у вас кодировка, я обнаружил, что VS-Code имеет отличную функцию, где в правом нижнем углу написано, что такое кодировка. Я думаю, что Notepad ++ также имеет аналогичную функцию.

Гаррет Хоффман
источник
Set-Content -Path $file -value $nullделает работу, и это не влияет на кодировку файлов. Проверьте также ss64 версиюtouch .
Антон Кроуглов,
3

Для сценария, который вы описали (когда файл не существует), это быстро и просто:

PS> sc example.txt $null

Тем не менее, другим распространенным способом использования touchявляется обновление метки времени файла. Если вы попытаетесь использовать мой scпример таким образом, он сотрет содержимое файла.

Джей Базузи
источник
1
Спасибо! Что scзначит? Редактировать: разобрался («Set Content»)
jsalonen
2

Чтобы создать пустой файл в Windows, способ поста следующий:

fsutil file createnew file.name 0

Ноль - размер файла в байтах, так что это также полезно для создания большого файла (они не будут полезны для тестирования сжатия, так как не содержат реальных данных и будут сжимать практически до нуля)

Джон Карлштедт
источник
2

На веб-странице http://xahlee.info/powershell/PowerShell_for_unixer.html предлагается:

new-item -type file [filename]

и это действительно создает новый файл нулевого размера.

Это не выполняет другую функцию Unix touch, а именно обновление временной метки, если имя файла уже существует, но вопрос подразумевает, что пользователь просто хочет создать файл нулевого размера в интерактивном режиме, не прибегая к Notepad.

ghostarbeiter
источник
1

Я использовал название «Write-File», потому что «Touch» не является утвержденным глаголом PowerShell . Я все еще называю это как прикосновение, как бы то ни было.

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

Использование:

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

Поддержка:

  • Пути в других каталогах
  • Credential для сетевых путей
  • Verbose, DebugИ WhatIfфлаги
  • подстановочные знаки (только обновление метки времени)
ошибка
источник
Команда New-Itemбыла предложена в четырех предыдущих ответах. Вы предоставили для этого 20-строчную упаковку. Можете ли вы объяснить более четко, какое преимущество имеет ваше решение перед предыдущими? Например, каковы эти Verbose, Debugи WhatIfфлаги, и т.д.?
Скотт
Одно важное различие между этим ответом и тем New-Item, что оно обновляет временную метку существующих файлов.
jpaugh