ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PowerShell 예제] Start-ThreadJob을 이용한 동시 처리 스크립트 구현
    Shell & CMD/PowerShell 2022. 7. 30. 20:39
    반응형

    지난 시간에 where, foreach 를 이용하여 특정 폴더내에서 txt 파일을 EUC-KR로 읽어 UTF-8로 변환했었다.

     

    주소 기반 데이터 정제작업에서 유용하긴 하지만 압축을 해제 한 후, 해당 폴더에 스크립트파일을 담은 뒤 실행해야 하는 선행 작업이 필요하기 때문에 자동화 작업이라 보긴 어려웠다. 그래서 스크립트를 아래와 같이 수정했다.

    # Parameter help description
    # Specifies a path to one or more locations.
    
    [CmdletBinding()]
    param (
        [string[]]
        $zipfiles
    )
    
    
    Write-Host "Convert Start :" ([DateTime]::Now).ToString("yyyy-MM-dd hh:mm:ss")
    
    $path = [System.IO.DirectoryInfo]::new($PWD.Path)
    
    if ($zipfiles.Count -eq 0) {
        $zipfiles = $path.GetFiles().Where({$_.Extension -eq ".zip"})
    }
    
    foreach ($zipfile in $zipfiles)
    {
        $zipfile = [System.IO.FileInfo]::new($zipfile)
        $out = Join-Path $path $zipfile.Name.Replace(".zip", [string]::Empty)
        if (Test-Path $out)
        {
            Remove-Item -Path $out -Force -Recurse
        }
        [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $out, [System.Text.Encoding]::GetEncoding("EUC-KR"))
    
        $txtfiles = Get-ChildItem $out | Where-Object {$_.Extension -eq ".txt"}
        foreach ($txtfile in $txtfiles)
        {
            Get-Content $txtfile -Encoding "EUC-KR" | 
            Set-Content $txtfile.FullName.Replace(".txt", ".csv", [System.StringComparison]::OrdinalIgnoreCase) -Encoding utf8
        }
    }
    
    Write-Host "Convert End :" ([DateTime]::Now).ToString("yyyy-MM-dd hh:mm:ss")

     

    작성 후 아래 5개의 zip 파일에 대해 컨버팅 작업을 수행했다.

    '202206_도로명주소 한글 전체분.zip',

    '202206_도로명주소 영어_전체분.zip',

    '202206_사물주소_전체분.zip',

    '202206_상세주소 표시_전체분.zip',

    '202206_상세주소DB_전체분.zip'

    Convert Start : 2022-07-30 07:13:01

    Convert End : 2022-07-30 07:25:03

    (약 12분 소요)

     

    시간이 다소 걸리게 되어 Start-ThreadJob 을 이용해보았다.

    # Parameter help description
    # Specifies a path to one or more locations.
    
    [CmdletBinding()]
    param (
        [string[]]
        $zipfiles
    )
    
    Write-Host "Convert Start :" ([DateTime]::Now).ToString("yyyy-MM-dd hh:mm:ss")
    
    $path = [System.IO.DirectoryInfo]::new($PWD.Path)
    
    if ($zipfiles.Count -eq 0) {
        $zipfiles = $path.GetFiles().Where({$_.Extension -eq ".zip"})
    }
    
     $jobs = @()
    
    
    foreach ($zipfile in $zipfiles)
    {
        $jobs += Start-ThreadJob -ScriptBlock {
            $zipfile = [System.IO.FileInfo]::new($using:zipfile)
            $path = $using:path
            $out = Join-Path $path $zipfile.Name.Replace(".zip", [string]::Empty)
            if (Test-Path $out)
            {
                Remove-Item -Path $out -Force -Recurse
            }
            [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $out, [System.Text.Encoding]::GetEncoding("EUC-KR"))
        
            $txtfiles = Get-ChildItem $out | Where-Object {$_.Extension -eq ".txt"}
            foreach ($txtfile in $txtfiles)
            {
                Get-Content $txtfile -Encoding "EUC-KR" | 
                Set-Content $txtfile.FullName.Replace(".txt", ".csv", [System.StringComparison]::OrdinalIgnoreCase) -Encoding utf8
            }
        }
    }
    Wait-Job -Job $jobs
    Write-Host "Convert End :" ([DateTime]::Now).ToString("yyyy-MM-dd hh:mm:ss")

    2022-07-30 08:07:23

     

    2022-07-30 08:20:22

    (약 11분 소요)

     

    상세주소 항목이 압도적으로 오래걸려서 뭔가 드라마틱하게 줄진 않았다. 그래도 조금이나마 시간단축하는데 의의를 두었다.

    참고로 Wait-Job 을 제거하면 작업을 background 형식으로 실행시킬 수 있으며, Get-Job 명령어로 실행중인 Job 확인이 가능하다. 유의할 점은 Job은 해당 명령을 실행한 파워셸 세션영역에 속하므로 다른 파워셸 창에서는 Get-Job 명령으로 확인되지 않으며, 실행중에 창을 닫으면 작업이 중단된다.

     

    출처 및 참조 :

    Start-ThreadJob (ThreadJob) - PowerShell | Microsoft Docs

    반응형

    댓글

Designed by Tistory.