
Я пытаюсь немного узнать о скриптах PowerShell и пытаюсь логически разбить скрипт, включающий этот фрагмент.
$destFolders | Foreach-Object { Copy-Item -Path $Source -dest (Join-Path $_ $destFileName) }
Если бы я писал это с нуля, я бы, наверное, написал так: в чем моя ошибка?
$destFolders | Foreach-Object { Copy-Item -Path $Source -dest ($_) }
Полный сценарий: - обратите внимание, что $destfilename не определен, возможно, это ошибка(?)
$path = "C:\a\"
$filename = (get-date).AddDays(-4).ToString('afileMMdd.txt')
$fileexisting = "$path\$filename"
$destfolders = "C:\b\", "C:\c\"
while(!(Test-Path $fileexisting)) {Start-Sleep 5}
$destfolders |
ForEach-Object {Copy-Item -Path $path\$filename -dest (Join-Path $_ $destfilename)}
решение1
Эта строка содержит элементы, такие как $destFolders
, $Source
и $destFileName
, которые, по-видимому, являются частью полного скрипта. Не зная их и их назначения, мой ответ может быть неверным.
ОднакоКопировать-элементКоманда может копировать элемент и переименовывать его. Кажется, это именно то, что делает первая строка скрипта. Ваша строка просто копирует элемент.
решение2
Кратко: Join-Path
позволяет поддерживать структуру папок, $destFileName
содержащую информацию о каталогах и файлах. (т.е. выглядит примерно так "somedirectory\myfile.txt"
, а не так myfile.txt
)
Итак, скрипт копирует файлы с C:\
диска на E:\
и D:\
.
Представьте, что существует файл C:\myfile.txt
:
Копирование с использованием обоих фрагментов дает одинаковый результат: ваш фрагмент говорит «скопировать из c:\ в d:\ и e:\ Я ничего не делаю с именами файлов, поэтому просто оставляю их прежними», другой фрагмент говорит «скопировать из c:\ в d:\myfile.txt и e:\myfile.txt. Я явно сообщаю вам имена файлов».
Представьте, что у вас есть файлC:\somedirectory\myfile.txt
Теперь есть разница, так как
$_
будет копировать вD:\myfile.txt
иE:\myfile.txt
снова. Он проигнорирует тот факт, что файл содержался внутри каталога. ИспользованиеJoin-path $_ $destFileName
будет означать, что файл копируется в D:\somedirectory\myfile.txtand E:\somedirectory\myfile.txt
решение3
Вы можете увидеть двойную обратную косую черту C:\a\\a6ile0309.PxP
(незначительная ошибка) и предположительно нежелательные символы в исходном выводе (серьезная ошибка):
a6ile0309.PxP
↑ ↑ ↑
↓ ↓ ↓
afile0309.txt
Последнее вызвано неправильным использованием спецификаторов формата f
иt
(get-date).AddDays(-4).ToString('afileMMdd.txt')
# ↑ ↑ ↑
ЧитатьФорматирование даты и временииФорматирование чисел и дат с использованием объекта CultureInfo:
f
Полная дата и время (длинная дата и короткое время)t
,%t
Первый символ в обозначении AM/PMОпределено в AMDesignator или PMDesignator, если таковые имеются. Укажите "%t", если шаблон формата не объединен с другими шаблонами формата.
На самом деле, f
в afile
результатах до последней миллисекунды(?) или тика(?) см. последнее примечание ниже. Честно говоря, я не знаю, можно ли это экранировать, поэтому попробуйте следующий фрагмент кода:
'--- original ---'
$path = "C:\a\"
$filename = (get-date).AddDays(-4).ToString('afileMMdd.txt')
$fileexisting = "$path\$filename"
$destfolders = "C:\b\", "C:\c\"
Write-host $filename, $fileexisting -ForegroundColor Yellow
### next WHILE never ends
### while(!(Test-Path $fileexisting)) {Start-Sleep 5}
'--- use rather ---'
$path = "C:\a\"
$filename = 'afile' + (get-date).AddDays(-4).ToString('MMdd') + '.txt'
$fileexisting = Join-Path $path $filename
$destfolders = "C:\b\", "C:\c\"
Write-host $filename, $fileexisting
Выход:
PS D:\PShell> D:\PShell\SU\1187865.ps1
--- original ---
a6ile0309.PxP C:\a\\a6ile0309.PxP
--- use rather ---
afile0309.txt C:\a\afile0309.txt
Пожалуйста, обрати вниманиечто
$filename = 'afile' + (get-date).AddDays(-4).ToString('MMdd') + '.txt'
можно записать как
$filename = '{0}{1}{2}' -f 'afile' , (get-date).AddDays(-4).ToString('MMdd') , '.txt'
и я не знаю, какая запись лучше или правильнее (PowerShellish).
Также обратите вниманиеразница:
PS D:\PShell> (get-date).ToString("yyyy-MM-dd-HH.mm.ss.ffffff") # six f
2017-03-13-22.23.35.897305
PS D:\PShell> (get-date).ToString("yyyy-MM-dd-HH.mm.ss.fffffff") # seven f
2017-03-13-22.30.08.4030682
PS D:\PShell> (get-date).ToString("f")
13 March 2017 22:23
PS D:\PShell> (get-date).ToString("ff")
20