Board logo

标题: [问题求助] PowerShell有条件地给某个文件夹中所有子文件夹分配指定数量的文件夹 [打印本页]

作者: 5i365    时间: 2022-1-6 19:14     标题: PowerShell有条件地给某个文件夹中所有子文件夹分配指定数量的文件夹

本帖最后由 5i365 于 2022-1-7 09:23 编辑

有两个主文件夹A和B,  要把A中的子文件夹分配【移动】到B的子文件夹中,
在分配到B下的每个子文件夹中之前,  要先检查该子文件夹的情况:  当其下只有1个OK文件夹, 才分配,【有文件不受影响】
A文件夹中的子文件夹名字如下
1 中
2 国
11 美
12 国
22 人
101 日
102 本
按子文件夹名字前的数字先后顺序分配【参考代码 Get-ChildItem “.\A”-Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { $_.FullName }】, 分配2个子文件夹到B下的符合上面要求的子文件夹中
分配中可能遇到的情况:
A下的子文件夹分完了: 则回显文件夹已经分完
A下的文件夹数量是奇数, 这样在给B下的某子文件夹分配过去时, 就只能分配一个过去了,此时不报错
可能因为A下没有足够的子文件夹,B下有些符合要求的子文件夹,仍然分不到文件夹,此时不报错

测试文件夹示例:
https://wss1.cn/f/7ar6432xz4e 复制链接到浏览器打开
作者: 5i365    时间: 2022-1-7 13:45

感觉这个示例太综合了,考查的点有多
作者: qixiaobin0715    时间: 2022-1-10 12:35

本帖最后由 qixiaobin0715 于 2022-1-10 12:40 编辑

回复 1# 5i365
这个用批处理应当也能解决。
但没有理解第一种情况的意思。
感觉第一种情况应当包含第2、3中情况。
作者: 5i365    时间: 2022-1-10 13:37

本帖最后由 5i365 于 2022-1-10 13:41 编辑

回复 3# qixiaobin0715


   感谢指正, 上面描述有点笼统, 第一种情况有包含第2、3中的情况。

pwershell跨平台真是牛X了, 一份代码两个系统运行, 确实不错

貌似,只限字符中串和文件处理之类的代码, 有些win专用的代码还是不能跨平台的

我用的一个音乐软件, 在win和mac都能安装, 刚用苹果系统, 不太熟悉, 所以考虑用ps, 一举多得
作者: idwma    时间: 2022-1-10 17:59

本帖最后由 idwma 于 2022-1-10 18:14 编辑
  1. Get-ChildItem “.\A”-Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a+=$_.FullName }
  2. dir .\b|?{$_.PSIsContainer}|%{if(test-path $_.fullname\ok){copy $a[$i++] $_.fullname -rec; copy $a[$i++] $_.fullname -rec}}
  3. if($a[$i] -eq $null){"分完"}
复制代码

作者: 5i365    时间: 2022-1-10 18:42

回复 5# idwma


  Test-Path : A positional parameter cannot be found that accepts argument '\ok'.
At line:2 char:34
+ dir .\b|?{$_.PSIsContainer}|%{if(test-path $_.fullname\ok){copy $a[$i ...
+                                  ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: ( [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.TestPathCommand

Test-Path : A positional parameter cannot be found that accepts argument '\ok'.
At line:2 char:34
+ dir .\b|?{$_.PSIsContainer}|%{if(test-path $_.fullname\ok){copy $a[$i ...
+                                  ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.TestPathCommand

Test-Path : A positional parameter cannot be found that accepts argument '\ok'.
At line:2 char:34
+ dir .\b|?{$_.PSIsContainer}|%{if(test-path $_.fullname\ok){copy $a[$i ...
+                                  ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.TestPathCommand

Index operation failed; the array index evaluated to null.
At line:3 char:4
+ if($a[$i] -eq $null){"分完"}
+    ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

请按任意键继续. . .
作者: idwma    时间: 2022-1-10 18:57

回复 6# 5i365


    忘了ok路径字符拼接没处理
  1. test-path "$($_.fullname+'\ok')"
复制代码

作者: 5i365    时间: 2022-1-10 20:02

回复 7# idwma


遇到两个情况:
1.我把copy改成了move 就报错了
2.从哪里可以设置每次分配的文件夹的数量, 例如,从A文件夹每次移动N个子文件夹到B下的某个符合要求的子文件夹中, 现在是每次移动两个

#&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a+=$_.FullName }
dir .\b|?{$_.PSIsContainer}|%{if(test-path "$($_.fullname+'\ok')"){move $a[$i++] $_.fullname -rec; move $a[$i++] $_.fullname -rec}}
if($a[$i] -eq $null){"分完"}
作者: idwma    时间: 2022-1-10 20:24

回复 8# 5i365
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k=2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a+=$_.FullName }
  4. dir .\b|?{$_.PSIsContainer}|%{if(test-path "$($_.fullname+'\ok')"){while($j++ -le $k){move $a[$i++] $_.fullname}}
  5. if($a[$i] -eq $null){"分完"}
复制代码

作者: 5i365    时间: 2022-1-10 21:12

回复 9# idwma


    Invoke-Expression : At line:3 char:30
+ dir .\b|?{$_.PSIsContainer}|%{if(test-path "$($_.fullname+'\ok')"){wh ...
+                              ~
Missing closing '}' in statement block or type definition.
At line:1 char:98
+ ... 歌曲文件夹 2.bat' | Select-Object -Skip 1 | Out-String | Invoke-Expression
+                                                         ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ParserError: ( [Invoke-Expression], ParseException
    + FullyQualifiedErrorId : MissingEndCurlyBrace,Microsoft.PowerShell.Commands.InvokeExpressionCommand

请按任意键继续. . .
作者: 5i365    时间: 2022-1-10 21:15

回复 9# idwma


   好像丢} 了,改成下面能执行了,但是B下的第一个子文件夹分配了, 其它的没有分配
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if (test-path "$($_.fullname + '\ok')") { while ($j++ -le $k) { move $a[$i++] $_.fullname } }
  6. if ($a[$i] -eq $null) { "分完" }
  7. }
复制代码

作者: idwma    时间: 2022-1-10 22:21

回复 11# 5i365
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if (test-path "$($_.fullname + '\ok')") { while ($j++ -le $k) { move $a[$i++] $_.fullname } }
  6. $j=$null
  7. if ($a[$i] -eq $null) { "分完" }
  8. }
复制代码

作者: 5i365    时间: 2022-1-11 08:17

回复 12# idwma


    刚看到, 现在双击批处理后, 成功移动了文件夹, 但是会报下面的错, 另外, $k=2 每次移动的文件夹数量却是3

Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:4 char:71
+ ... ($_.fullname + '\ok')") { while ($j++ -le $k) { move $a[$i++] $_.full ...
+                                                          ~~~~~~~~
    + CategoryInfo          : InvalidData: ( [Move-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCom
   mand

Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:4 char:71
+ ... ($_.fullname + '\ok')") { while ($j++ -le $k) { move $a[$i++] $_.full ...
+                                                          ~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Move-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCom
   mand

分完
请按任意键继续. . .
作者: qixiaobin0715    时间: 2022-1-11 09:08

回复 1# 5i365
来个纯批的吧:
  1. @echo off
  2. set n=10000
  3. setlocal enabledelayedexpansion
  4. for /f "tokens=1*" %%i in ('dir /b /ad A') do (
  5.     set /a n+=%%i
  6.     set "_!n!=%%i %%j"
  7.     set n=10000
  8. )
  9. for /f "delims=" %%k in ('dir /b /ad B') do (
  10.     if exist "B\%%k\ok" (
  11.         pushd "B\%%k"
  12.         dir /b /ad|find /v "ok">nul||(
  13.             set /a m+=1
  14.             set "#!m!=B\%%k"
  15.         )
  16.         popd
  17.     )
  18. )
  19. for /f "tokens=1* delims==" %%a in ('set _') do (
  20.     set str=%%b
  21.     set /a x+=1
  22.     set /a "y=(x+1)/2"
  23.     for /f "delims=" %%c in ("#!y!") do if exist "!%%c!" move "A\%%b" "!%%c!\"
  24. )>nul
  25. if not exist "A\!str!" echo,文件夹已经分完!!!
  26. pause
复制代码

作者: idwma    时间: 2022-1-11 14:43

回复 13# 5i365
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if (test-path "$($_.fullname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $a[$i++] $_.fullname} } }
  6. $j=$null
  7. }
  8. if ($a[++$i] -eq $null) { "分完" }
复制代码

作者: 5i365    时间: 2022-1-11 14:50

回复 15# idwma


    Index operation failed; the array index evaluated to null.
At line:4 char:70
+ ... lname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $ ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: ( [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

Index operation failed; the array index evaluated to null.
At line:4 char:70
+ ... lname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $ ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

Index operation failed; the array index evaluated to null.
At line:4 char:70
+ ... lname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $ ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

Index operation failed; the array index evaluated to null.
At line:4 char:70
+ ... lname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $ ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

Index operation failed; the array index evaluated to null.
At line:4 char:70
+ ... lname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $ ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

Index operation failed; the array index evaluated to null.
At line:4 char:70
+ ... lname + '\ok')") { while ($j++ -lt $k) { if ($a[$i] -ne $null){move $ ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

请按任意键继续. . .
作者: idwma    时间: 2022-1-11 15:07

回复 16# 5i365
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if (test-path "$($_.fullname + '\ok')") { while ($j++ -lt $k) { if ($a[$i++] -ne $null){move $a[$i-1] $_.fullname} } }
  6. $j=$null
  7. }
  8. if ($a[++$i] -eq $null) { "分完" }
复制代码

作者: 5i365    时间: 2022-1-11 15:40

回复 17# idwma


    可以分了, 但是新问题来了,  A里7个文件夹, B里有三个, 执行脚本后, B里每个文件夹分到了A里的两个文件夹, 但此时我再次执行脚本, 却又把A余下的1个分给了B里的第一个文件夹, 但, 此时并不满足条件, 因为它里面已经分到两个文件夹了, 并不是只有一个OK文件夹
作者: idwma    时间: 2022-1-11 16:20

回复 18# 5i365
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if ((test-path $($_.fullname + '\ok')) -and (dir $_.fullname).count -lt 1) { while ($j++ -lt $k) { if ($a[$i++] -ne $null){move $a[$i-1] $_.fullname} } }
  6. $j=$null
  7. }
  8. if ($a[++$i] -eq $null) { "分完" }
复制代码

作者: 5i365    时间: 2022-1-11 16:29

回复 19# idwma


    不报错, 也没有移动文件夹
作者: idwma    时间: 2022-1-11 16:55

本帖最后由 idwma 于 2022-1-11 18:17 编辑

回复 20# 5i365


    这次测了是可以的
怕不是又是powershell版本问题,2.0dir只有一个时count的数不是1
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if ((test-path $_.fullname + '\ok')) -and $(dir $_.fullname|%{$n++};$n;$n=$null) -lt 2) { while ($j++ -lt $k) { if ($a[$i++] -ne $null){move $a[$i-1] $_.fullname} } }
  6. $j=$null
  7. }
  8. if ($a[++$i] -eq $null) { "分完" }
复制代码

作者: 5i365    时间: 2022-1-11 19:46

回复 21# idwma


    Invoke-Expression : At line:4 char:37
+     if ((test-path $_.fullname + '\ok')) -and $(dir $_.fullname|%{$n+ ...
+                                        ~
Missing statement block after if ( condition ).
At line:3 char:36
+ dir .\b | ?{ $_.PSIsContainer } | %{
+                                    ~
Missing closing '}' in statement block or type definition.
At line:4 char:88
+ ...  + '\ok')) -and $(dir $_.fullname|%{$n++};$n;$n=$null) -lt 2) { while ...
+                                                                 ~
Unexpected token ')' in expression or statement.
At line:6 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
At line:1 char:98
+ ... 歌曲文件夹 2.bat' | Select-Object -Skip 1 | Out-String | Invoke-Expression
+                                                         ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ParserError: ( [Invoke-Expression], ParseException
    + FullyQualifiedErrorId : MissingStatementBlock,Microsoft.PowerShell.Commands.InvokeExpressionCommand

请按任意键继续. . .
作者: idwma    时间: 2022-1-11 21:50

回复 22# 5i365
  1. #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
  2. $k = 2
  3. Get-ChildItem ".\A" -Directory | Sort-Object { [int]($_.Name -split '\s+')[0] } | foreach-Object { [array]$a += $_.FullName }
  4. dir .\b | ?{ $_.PSIsContainer } | %{
  5. if ((test-path $($_.fullname + '\ok')) -and $(dir $_.fullname|%{$n++};$n;$n=$null) -lt 2) { while ($j++ -lt $k) { if ($a[$i++] -ne $null){move $a[$i-1] $_.fullname} } }
  6. $j=$null
  7. }
  8. if ($a[++$i] -eq $null) { "分完" }
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2