2014-12-19 2 views
0

에 FOREACH에 여러 명령과 함께/F위한 일괄 변환, @Magoo 7-ZIP으로 압축 된 파일에 대한/F 명령을 운동으로 도와 충분히 좋은이었다은 몇 시간 전 PowerShell을

Using FOR or FORFILES batch command to individually archive specific files

그 이후로 저는 다소 확장했으며 더 정교한 것들을 원합니다. 그러나이 질문을 간단하게하기 위해이 작업을 시도하고 수행하기위한 기본 사항을 포함 시켰습니다.이 작업은별로 성공하지 못했습니다.

필자는 PowerShell을 처음 사용하기 때문에 앞으로 배치 파일 대신이 파일을 사용하는 특별한 이유가 있습니다. 좀 더 숙련 된 사용자는 PowerShell에서 이러한 진술을 사용하여 성능이 저하되지만, 중요한 문제는 아닙니다. 나는 IF 몇 가지 문제에있어

$env:Path += ";C:\Program Files\7-Zip" 
$sourcedir = read-host "Enter the directory to archive: " 
foreach ($aname in { 
    'cmd /c dir /s/b /a-d "$sourcedir\*.iso" ' 
    'cmd /c dir /s/b /a-d "$sourcedir\*.daa" ' 
    'cmd /c dir /s/b /a-d "$sourcedir\*.nrg" ' 
    'cmd /c dir /s/b /a-d "$sourcedir\*.flp" '} 
) { 
    IF NOT EXIST $aname.7z (
     echo 7z a -t7z "$aname.7z" "$aname" -mx9 -mmt >> Z:\test\7z-log.txt 
     ECHO "$aname" archived. 
    ) ELSE (
     ECHO "$aname" archive file already exists. 
     ) 
    } 

문을 존재하고 내가 IF를 제거하고 한 줄 ECHO했다 경우에도 단지 더를 단순화하기 위해,하지만 난 내가 원하는 것을 출력을 얻을 수 없었다 .

그래서 나는 다른 접근 시도 :

$env:Path += ";C:\Program Files\7-Zip" 
$sourcedir = read-host "Enter the directory to archive: " 
$dir_iso = ForEach-Object { cmd /c dir /s/b /a-d "$sourcedir\*.iso" } 
$dir_daa = ForEach-Object { cmd /c dir /s/b /a-d "$sourcedir\*.daa" } 
$dir_nrg = ForEach-Object { cmd /c dir /s/b /a-d "$sourcedir\*.nrg" } 
$dir_flp = ForEach-Object { cmd /c dir /s/b /a-d "$sourcedir\*.flp" } 
foreach ($aname in $dir_iso,$dir_daa,$dir_nrg,$dir_flp) { 
     ECHO "$aname" archived. 
     } 

을하지만이 무슨 짓을했는지, 다음 추가 그 세트에 "보관"함께 각 유형의 각 항목을 뭉쳐있다. 뭔가 같이 :

C:\folder1\iso1.iso C:\folder1\iso2.iso C:\folder1\iso3.iso archived. 
C:\folder2\image.nrg archived. 
C:\folder3\app1.flp C:\folder3\app2.flp archived. 

대신 :

C:\folder1\iso1.iso archived. 
C:\folder1\iso2.iso archived. 
C:\folder1\iso3.iso archived. 
C:\folder2\image.nrg archived. 
C:\folder3\app1.flp archived. 
C:\folder3\app2.flp archived. 

나는이 일을 점점 진짜 힘든 시간을 보내고 있습니다. 누구든지 도와 줄 수 있습니까?

감사합니다.

답변

1

여기를 참조하면 파일 시스템 구체적 cmd /c dir /s/b /a-d "$sourcedir\*.iso"

$dir_iso = ForEach-Object { cmd /c dir /s/b /a-d "$sourcedir\*.iso" } 

에서 파일 정보를 얻기 위해 이것을 사용하는 것입니다 가장 먼저하는 일. 이 Get-ChildItem

$dir_iso = Get-ChildItem -Path $sourcedir -Filter "*.iso" -Recurse -File | Select-Object -ExpandProperty FullName 
  • Path 쉽게 번역 할 것은 당신이
  • File
  • 을 체크 .iso로
  • Recurse 모든 하위 디렉토리로 끝나는 파일 만 원하는 당신이
  • Filter
  • 을 확인하려는 폴더의 파일 경로입니다 디렉토리가 아닌 파일 만 반환합니다 (PowerShell 3.0 이상!).
  • Select-Object -ExpandProperty FullName은 배열에서 찾은 파일의 전체 경로를 반환합니다.

IF EXIST 거기이와 몇 가지 좋은 방법이 있지만 가장 간단한 전이시는

$dir_iso + $dir_daa + $dir_nrg + $dir_flp | ForEach-Object{ 
    Do Stuff 
} 

아마 구축 할 수 것 ForEach 루프 foreach ($aname in $dir_iso,$dir_daa,$dir_nrg,$dir_flp)에 관해서는 Test-Path

If(Test-Path "$aname.7z"){ 
    Do stuff... 
} 

로 대체 될 수있다 하나의 변수에있는 파일 컬렉션은 함께 배열을 피하기 위해 시작합니다.

$files = Get-ChildItem -Path $sourcedir -Recurse -File | Where-Object{$_.Extension -match "(iso|daa|nrg|flp)$" } | Select-Object -ExpandProperty FullName 

$files | ForEach-Object{ 
    Write-Host "$_" 
} 
0

echo 대신 write-host를 사용하십시오. 다차원 배열이므로 내부 루프가 필요합니다.

foreach ($aname in $dir_iso,$dir_daa,$dir_nrg,$dir_flp) { 
    foreach ($bname in $aname) { 
     write-host "$bname" archived. 
    } 
} 
0

또 다른 가능성; 이 명령은 별도의 변수에 저장하는 대신 명령을 함께 처리합니다.

Get-Item $sourcedir\* | 
Where {$_.Extension -like ".iso" -or $_.Extension -like ".daa" -or $_.Extension -like ".nrg" -or $_.Extension -like ".flp"} | 
Foreach-Object { 
    if (-Not (Test-Path "$_.BaseName.7z")) 
    { 
     Write-Host $_.FullName not yet archived. 
    } 
    else 
    { 
     Write-Host $_.FullName already archived. 
    } 
} 
+1

당신이 그렇게 할 예정이라면 간단히 일치를 사용할 수도 있습니다. '$ _. Extension -match "(iso | daa | nrg | flp) $"'. 파일 구조의 크기에 따라 성능면에서 필터가 더 좋을 수 있습니다. – Matt

관련 문제