Powershell 스크립트 수정 좀 도와주세요 (택스트 중복 체크)

dateno1   
   조회 2399   추천 0    

쪽팔리면 질문하지 맙시다. 소중한 답변 댓글을 삭제하는건 부끄러운 일 입니다 

Get-Content "./text.txt" | Group-Object | Where-Object { $_.Count -gt 1 } | Select -ExpandProperty Name


현제 내용은 이거 1줄이 끝입니다 (text.txt를 열어서 중복 라인을 체크후 표시해줍니다)


굳이 ps1 포맷을 안 쓰고, Python같은걸로 처리해도 상관 없습니다 (아니면 달성 가능한 소프트를 소개해주셔도 됩니다)


목표는 2가지입니다 (둘중 하나 달성 가능하면 됩니다)

1. 현제 구조면 싱글 스레드로 처리하다보니 수십만 (현제 40만대인데 차후 더 늘어날 수 있습니다) 라인 처리에 너무 오래 걸립니다


가능하다면 분할해서 4~6스레드정도로 처리하고 싶습니다 (전체 라인을 카운터해서 필요한 스레드 숫자로 나눈후 시작 지점을 각각 그만큼 더해서 지정하면 될꺼같습니다)


2. 진척도 표시및 이어서 처리 기능을 추가하고 싶습니다


현제 구조면 완료까지 아무것도 안 뜨고, 1~끝까지 처리인데 현제 처리중인 라인의 수치를 표시 + 실행시 시작과 끝을 입력하면 해당 구간을 처리하고, 안 하면 처음~끝까지 처리하게 하고자 합니다


만일 이게 가능해지면 여러개 실행해서 라인을 지정해서 실행하면 멀티 스레드로 처리가 가능하므로 1번이 필요 없어집니다


결국 2가지라 적었지만, 궁극적으로는 멀티 스레드로 처리하는게 목표라 보시면 됩니다 (싱글 스레드로 41.5만 라인 택스트 처리하니 끔찍한 시간이 걸립니다)

맨날 삽질만 하고 삽니다

http://www.2cpu.co.kr/hardware_2014/44147
컴 케이스 작다고 불타거나 하지 않아요

짧은글 일수록 신중하게.
화정큐삼 2024-03
ChatGPT 3.5 로 돌린건데, 아마 정확히 한번에 나오진 않았을것 같습니다. 좀더 다듬으시면 원하시는 스크립트가 나오지 않을까요?

GPT 질의)
Get-Content "./text.txt" | Group-Object | Where-Object { $_.Count -gt 1 } | Select -ExpandProperty Name
1. 전체 라인을 분할해서 4~6스레드정도로 처리 (전체 라인을 카운터해서 필요한 스레드 숫자로 나눈후 시작 지점을 각각 그만큼 더해서 지정)
2. 진척도 표시 및 일시중지 및  계속진행처리 기능 추가

GPT 답변 )
: 먼저, 전체 라인을 분할하여 여러 스레드에서 처리할 수 있도록 작업할 수 있습니다. 이를 위해서는 파일의 전체 라인 수를 세고, 그 수에 따라 적절한 수의 스레드로 분할합니다. 그런 다음, 각 스레드가 처리해야 할 라인 범위를 계산합니다.

#-----------------------------------------
# 파일의 전체 라인 수 계산
$totalLines = Get-Content "./text.txt" | Measure-Object -Line | Select-Object -ExpandProperty Lines

# 사용할 스레드 수 설정 (여기서는 예시로 4~6 사이의 스레드를 사용)
$threadCount = Get-Random -Minimum 4 -Maximum 7

# 각 스레드가 처리할 라인 범위 계산
$linesPerThread = [math]::Ceiling($totalLines / $threadCount)

# 각 스레드의 시작 지점 계산
$threadRanges = @()
$startLine = 1
for ($i = 1; $i -le $threadCount; $i++) {
    $endLine = [math]::Min($startLine + $linesPerThread - 1, $totalLines)
    $threadRanges += "$startLine-$endLine"
    $startLine = $endLine + 1
}
#-----------------------------------------

이제 $threadRanges 배열에는 각 스레드가 처리해야 할 라인의 범위가 저장됩니다.

: 다음으로, 진척도 표시 및 일시중지/계속진행처리 기능을 추가할 수 있습니다. 이를 위해서는 각 스레드가 라인을 처리할 때마다 진행 상황을 표시하고, 필요한 경우 사용자 입력을 받아 작업을 일시 중지하거나 계속 진행합니다.

#-----------------------------------------
# 각 스레드에서 진행 상황을 표시하고 사용자 입력을 처리하는 함수 정의
function ProcessLines {
    param (
        [string]$range
    )

    $startLine, $endLine = $range -split '-'

    for ($lineNumber = $startLine; $lineNumber -le $endLine; $lineNumber++) {
        # 각 라인을 처리하는 작업 수행
        # 여기에 실제 작업 내용을 추가

        # 진행 상황 표시
        Write-Host "Processing line $lineNumber/$totalLines"

        # 사용자 입력 확인 (일시 중지 또는 계속 진행)
        $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").Character
        if ($key -eq 'p') {
            # 'p' 키를 누르면 일시 중지
            Write-Host "작업이 일시 중지되었습니다. 계속하려면 'c'를 입력하세요."
            do {
                $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").Character
            } while ($key -ne 'c')
            Write-Host "작업을 계속합니다."
        }
    }
}

# 각 스레드마다 작업 시작
foreach ($range in $threadRanges) {
    Start-ThreadJob -ScriptBlock {
        param (
            [string]$range
        )
        ProcessLines $range
    } -ArgumentList $range
}

# 모든 스레드 작업이 완료될 때까지 대기
Get-Job | Wait-Job

# 모든 작업 완료 후 스레드 종료
Get-Job | Remove-Job
#-----------------------------------------

위의 예제에서는 각 스레드가 각 라인을 처리하는 가상의 작업을 수행하고, 그 과정에서 진행 상황을 표시하고 사용자 입력을 받습니다. 실제 작업에 맞게 스크립트를 수정하십시오.
     
dateno1 2024-03
시험해보니 job 생성 시도를 하고, 전체를 입력한 스레드 숫자만큼으로 나누어서 산출하는것까진 정상인데, 정작 처리해야할 부분에 내용 추가해줘도 해당 내용 실행은 안 하네요
민호양 2024-03
Group-Object 가 다 읽고 묶기때문에 오래걸립니다.
Where-Object { $_.Count -gt 1 } 는 오히려 별 시간 안걸릴겁니다.
각 단계를 쪼개 변수에 넣고 실행을 하면 오래걸리는 병목이 어디인지 보일겁니다.
a = Get-Content "./text.txt"
b = a | Group-Object
...
system32 2024-03
python3 로 짠 소스입니다.import os
import threading

class LineProcessor:
    def __init__(self, filename):
        self.filename = filename
        self.lock = threading.Lock()
        self.total_lines = 0
        self.processed_lines = 0
        self.duplicates = {}

    def count_lines(self):
        with open(self.filename, 'r') as file:
            for line_number, line in enumerate(file, start=1):
                self.total_lines += 1

    def process_lines(self, start=None, end=None):
        with open(self.filename, 'r') as file:
            if start:
                file.seek(start)
            if end:
                chunk_size = end - start
            else:
                chunk_size = os.path.getsize(self.filename)

            for _ in range(chunk_size):
                line = file.readline()
                if not line:
                    break
                self.processed_lines += 1
                if line in self.duplicates:
                    with self.lock:
                        print(f"Duplicate line '{line.strip()}' found at line number(s): {', '.join(map(str, self.duplicates[line]))}")
                else:
                    self.duplicates.setdefault(line, []).append(self.processed_lines)

    def process_chunk(self, start, end):
        self.process_lines(start, end)
        with self.lock:
            print(f"Processed chunk from {start} to {end}. Progress: {self.processed_lines}/{self.total_lines}")

def find_duplicates(filename, num_threads=4):
    processor = LineProcessor(filename)
    processor.count_lines()
    chunk_size = processor.total_lines // num_threads

    threads = []
    for i in range(num_threads):
        start = i * chunk_size
        end = (i + 1) * chunk_size if i < num_threads - 1 else None
        thread = threading.Thread(target=processor.process_chunk, args=(start, end))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    # print("Duplicate lines found:", processor.duplicates)

if __name__ == "__main__":
    filename = "text.txt"
    find_duplicates(filename)

나쁘지 않게 결과를 뱉어주네요.


QnA
제목Page 495/5725
2014-05   5244716   정은준1
2015-12   1770112   백메가
2020-02   2383   행복하세
2019-12   2383   ocarina
2020-01   2383   비비BB
2022-05   2383   malalari
2023-11   2383   seoulmetro
2021-04   2383   하나비
2023-04   2384   VSPress
2018-12   2384   진신두
2024-03   2384   NiteFlite9
2023-07   2384   류류류
2024-06   2384   승리의샌디…
2023-10   2384   죠슈아
2024-04   2384   신은왜
2021-04   2384   김효수
2023-02   2385   정의석
2021-11   2385   리드2cpu
2024-03   2385   5620SAM
2021-07   2385   돔이
2021-07   2385   라이크유
2023-05   2385   이매망량2