简体   繁体   English

如何在 for 循环中运行 powershell 脚本?

[英]How can I run a powershell script in a for loop?

I have been tasked to sort home video and pictures for my family.我的任务是为我的家人整理家庭录像和照片。 The scripts that I have work fine but I have to manually run them against each directory.我的脚本运行良好,但我必须针对每个目录手动运行它们。 How can I run my script against all child-items that are only at 1 Depth?如何针对仅处于 1 深度的所有子项运行我的脚本?

My current crude scripts are as follows:我目前的粗略脚本如下:

$current_dir = Split-Path -Path $pwd -Leaf
$new_path = "H:\sorted\$current_dir\pictures"

Get-ChildItem -R . -Include ('*.jpg', '*.jpeg', '*.png') | Move-Item -Destination (New-Item -Force -Path "$new_path" -Type Directory)
$current_dir = Split-Path -Path $pwd -Leaf
$new_path = "H:\sorted\$current_dir\videos"

Get-ChildItem -R . -Include ('*.mp4', '*.mkv', '*.3pg','*.flv', '*.mov', '*.gif') | Move-Item -Destination (New-Item -Force -Path "$new_path" -Type Directory)

Example file tree示例文件树

E:.
├───April9383
├───April98765
│   └───carson
├───Cathy
├───Cathy(1)
├───Charlie
│   ├───Photos
│   └───Videos
├───daleville

I want the end structure to look like Charlie does in the example.我希望最终结构看起来像 Charlie 在示例中所做的那样。 How can I run both of these with a loop from E: ?我怎样才能用 E: 的循环运行这两个?

I have tried我努力了

$sub_dir = $(Get-ChildItem . -Depth 1)

foreach ($sub in $sub_dir)  {
    picture-sort.ps1
}

but this took the name of the folder that all of the example files were stored in and not that of "April9383" etc但这采用了存储所有示例文件的文件夹的名称,而不是“April9383”等的名称

SOLVED:解决了:

I ended up going with @Santiago's response but edited a bit as it wasn't working exactly how I needed it.我最终接受了@Santiago 的回复,但进行了一些编辑,因为它并没有完全按照我的需要工作。

I took this and ran with it to end up with我拿了这个并用它运行以结束

$base = "E:\sorted"
$current_dir = $pwd
# get the folders 1 level deep and enumerate
Get-ChildItem . -Depth 0 -Directory | ForEach-Object {
    # join the destination with this folder's Name
    $path = Join-Path $base -ChildPath $_.Name
    $pic_path = "$path\pictures"
    $vid_path = "$path\videos"
    
    #source dirs
    $stripped_dest_path = Split-Path -Path $path -Leaf
    $src_path = Join-Path $current_dir  $stripped_dest_path 
    
    #Print statement
    Write-Output "Copying pictures from $src_path to $pic_path"
    # get and move all pictures
    Get-ChildItem -R $src_path -Include ('*.jpg', '*.jpeg', '*.png') |
        Copy-Item -ErrorAction SilentlyContinue -Destination (New-Item -Force -Path "$pic_path" -Type Directory)

    #Print statement
    Write-Output "Copying videos from $src_path to $vid_path"
    # get and move all videos
    Get-ChildItem -R $src_path -Include ('*.mp4', '*.mkv', '*.3pg','*.flv', '*.mov', '*.gif', '*.avi') |
        Copy-Item -ErrorAction SilentlyContinue -Destination (New-Item -Force -Path "$vid_path" -Type Directory)


    Write-Output "END OF LOOP"
}

You're almost there, just need to put all your logic inside the loop:你几乎就在那里,只需要将所有逻辑放在循环中:

$base = "H:\sorted"
# get the folders 1 level deep and enumerate
Get-ChildItem . -Depth 1 -Directory | ForEach-Object {
    # join the destination with this folder's Name
    $path = Join-Path $base -ChildPath $_.Name

    # get and move all pictures
    $_ | Get-ChildItem -Recurse -Include '*.jpg', '*.jpeg', '*.png' |
        Move-Item -Destination (New-Item -Path (Join-Path $path -ChildPath 'Pictures') -Type Directory -Force)

    # get and move all videos
    $_ | Get-ChildItem -Recurse -Include '*.mp4', '*.mkv', '*.3pg','*.flv', '*.mov', '*.gif' |
        Move-Item -Destination (New-Item -Path (Join-Path $path -ChildPath 'videos') -Type Directory -Force)
}

I ended up going with @Santiago's response but edited a bit as it wasn't working exactly how I needed it.我最终接受了@Santiago 的回复,但进行了一些编辑,因为它并没有完全按照我的需要工作。

I took this and ran with it to end up with我拿了这个并用它运行以结束

$base = "E:\sorted"
$current_dir = $pwd
# get the folders 1 level deep and enumerate
Get-ChildItem . -Depth 0 -Directory | ForEach-Object {
    # join the destination with this folder's Name
    $path = Join-Path $base -ChildPath $_.Name
    $pic_path = "$path\pictures"
    $vid_path = "$path\videos"
    
    #source dirs
    $stripped_dest_path = Split-Path -Path $path -Leaf
    $src_path = Join-Path $current_dir  $stripped_dest_path 
    
    #Print statement
    Write-Output "Copying pictures from $src_path to $pic_path"
    # get and move all pictures
    Get-ChildItem -R $src_path -Include ('*.jpg', '*.jpeg', '*.png') |
        Copy-Item -ErrorAction SilentlyContinue -Destination (New-Item -Force -Path "$pic_path" -Type Directory)

    #Print statement
    Write-Output "Copying videos from $src_path to $vid_path"
    # get and move all videos
    Get-ChildItem -R $src_path -Include ('*.mp4', '*.mkv', '*.3pg','*.flv', '*.mov', '*.gif', '*.avi') |
        Copy-Item -ErrorAction SilentlyContinue -Destination (New-Item -Force -Path "$vid_path" -Type Directory)


    Write-Output "END OF LOOP"
}

This should work:这应该工作:

$PictureFiles = @('*.jpg', '*.png')
$VideoFiles = @('*.mkv', '*.mp4')

$MyFiles = Get-ChildItem H:\sorted -Recurse -File -Include @($PictureFiles + $VideoFiles) -Depth 1

foreach ($File in $MyFiles) {
    #Videos
    if ($File.Extension -in ($VideoFiles -replace '\*')) {
        mkdir ($File.DirectoryName + "\Videos\") -Force
        Move-Item -Path $File.FullName -Destination ($File.DirectoryName + "\Videos\" + $File.Name) -Force
    }

    #Pictures
    if ($File.Extension -in ($PictureFiles -replace '\*')) {
        mkdir ($File.DirectoryName + "\Pictures\") -Force
        Move-Item -Path $File.FullName -Destination ($File.DirectoryName + "\Pictures\" + $File.Name) -Force
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM