【问题标题】:Create Directory Using Partial Path使用部分路径创建目录
【发布时间】:2017-08-16 15:48:13
【问题描述】:

问题

在 PowerShell 中,是否可以使用包含通配符的部分路径(例如:C:\*\SomeFolder\MyBackup)创建新文件目录?如果有,怎么做?

详情

我正在使用 PowerShell 创建一个应用程序,该应用程序的一部分让用户指定一个备份目录。这个目录可能是一个确切的路径,但我也希望可以使用通配符。话虽如此,我知道如果提供的路径是绝对的,我可以轻松使用MD C:\SomePath\New-Item "C:\SomePath\" -FileType Directory;但是,每当我尝试使用通配符执行此操作时,它都会失败。

示例:这些都在我尝试时失败了

  1. MD "C:\*\MyBackups\AppBackup"
  2. New-Item "C:\*\MyApp\Backup" -FileType Directory
  3. $fullPath = "C:\*\MyApp\Backup" | Resolve-Path
  4. $fullPath = Resolve-Path "C:\*\MyApp\Backup"
  5. $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("C:\*\MyApp\Backup")

现在,我知道部分失败是通配符本身,因为该命令不理解如何解释它。

我研究了诸如New-ItemConvert-PathResolve-PathSplit-Path 之类的东西,但找不到与我想做的事情相关的任何东西。

【问题讨论】:

  • 相对于什么?
  • “相对路径”的意思是“相对于我当前的位置”。 .. 表示“当前位置的父级”。添加\ 和另一个.. 表示“父母的父母”。因此,如果您的当前位置是C:\Program Files (x86)\Microsoft Office\Office14,则符号..\.. 指的是C:\Program Files (x86)
  • 更新了基础帖子以更好地澄清......我的意思是“部分路径”而不是“相对路径”
  • 它需要通过某种方法知道 * 表示什么。它可以是相对的,但必须在尝试执行新项目之前捕获该相对位置。 * 是用户输入的吗?
  • 部分路径是路径的一部分。您所拥有的是带有通配符的路径。

标签: powershell wildcard filepath create-directory


【解决方案1】:

mdNew-Item 周围的包装函数的别名,它需要一个准确的路径。如果你想创建一个基于通配符路径的目录,你需要这样的东西:

Get-ChildItem 'C:\*\MyBackups' | ForEach-Object {
    New-Item -Type Directory -Path $_.FullName -Name 'MyBackup' | Out-Null
}

请注意,路径中的通配符通常只覆盖一个层次结构。如果你想在 C: 驱动器上找到 any 子文件夹 MyBackups,你需要这样的方法:

Get-ChildItem 'C:\' -Filter 'MyBackups' -Directory -Recurse | ForEach-Object {
    New-Item -Type Directory -Path $_.FullName -Name 'MyBackup' | Out-Null
}

【讨论】:

  • 嗯,我一直认为通配符可以递归地起作用......所以搜索C:\*\MyBackups实际上是在寻找C:\Temp\SubFolder\MyBackups会找不到这个吗?在示例 2 中:如果我们知道路径来自用户的输入并且“MyBackups”不存在,那么这个示例最初不会失败吗?据我了解,这是在一个固定点上递归搜索,然后添加一个具有相同名称的附加子目录。我希望最终目录类似于:C:\Temp\SubFolder\MyBackups\MyBackups
  • 第二个示例正在查找现有文件夹 MyBackups 并在它找到的文件夹中创建一个子文件夹 MyBackup(例如 C:\Temp\Subfolder\MyBackups\MyBackup)。如果找不到现有文件夹MyBackups,则不会创建备份文件夹。
  • 嗯...那么这个例子不太适合我的需要;但是,这给了我一个想法。如果成功我会发布它。
  • 你需要某种锚。否则你怎么知道在哪里创建文件夹?
  • 好吧,我也想到了这一点,我想我可以解析用户的输入并获取父目录的名称并将其用作锚点。但我在让它正常工作时遇到了一些麻烦
【解决方案2】:

如果您尝试获取用户输入并使其表示 *,那么您需要在代码中表示它。唯一让我感到困惑的是你有通配符。我认为我不完全理解通配符在您的脚本中的用途。

$backupTemplate = 'MyBackups\AppBackup'

#This can be a lot of different methods of input, from a Read-Host or what I have below
$dirSelector = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{ SelectedPath = Get-Location }
$dirSelector.ShowDialog() | Out-Null
$dirSelector.SelectedPath

$bckupDir = "$($dirSelector.SelectedPath)\$backupTemplate"

#EDIT: You were indicating below you needed to find the parent directory for the 'anchor'. Added this here for that.
$parentDir = (Get-Item $dirSelector.SelectedPath).Parent.FullName

if(-not (Test-Path -Path $bckupDir))
{
    New-Item -Path $bckupDir
}

#Execute your code here on whatever is doing the backup.

编辑/添加:

如果您遇到的问题是用户设置了一次备份目录,然后可能不记得它的位置,那么您应该考虑将此变量存储在用户可以在您的 cmdlet 和您的 cmdlet 中调用的位置可以访问使用。

执行此操作的一种非常常见的方法是创建一个文件,该文件包含用户针对您尝试完成的任何设置所做的设置。

这样做的一个好方法是创建一个标准对象,然后将其导出为 CliXML(或 JSON 或您喜欢使用的任何格式),如下所示:

$userSettings = New-Object -TypeName psobject
$userSettings | Add-Member -MemberType NoteProperty -Name User -Value $env:USERNAME
$userSettings | Add-Member -MemberType NoteProperty -Name LastUpdate -Value $(Get-Date -format u)
$userSettings | Add-Member -MemberType NoteProperty -Name BackupDirectory -Value $dirSelector.SelectedPath

$userSettings | Export-Clixml -Path "$env:USERPROFILE\psUserProf.xml"

#when you need to get the users backup folder in the future you just import the profile and work from there
$userSettings = Import-Clixml -Path "$env:USERPROFILE\psUserProf.xml"
$userSettings.BackupDirectory

但请注意,如果您的用户拥有多台计算机,则您需要为这些设置提供一种遵循它们的方法。

【讨论】:

  • 我明白你有多困惑。 * 本身不是用户输入,提供的路径是。所以我试图看看是否可以允许用户提供通配符,并使用该通配符解析完整路径
  • @Brandon 我在上面的编辑中添加了更多细节。
猜你喜欢
  • 2019-06-08
  • 2013-09-07
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 2010-11-25
  • 2014-03-08
相关资源
最近更新 更多