Windows PowerShell과 부분 문자열 일치를 기반으로 텍스트 파일에서 전체 줄 삭제


22

따라서 정렬 해야하는 큰 텍스트 파일이 여러 개 있으며 주어진 키워드가 포함 된 모든 줄을 제거합니다. 기본적으로 다음 줄이 있으면

이 테스트되지 않습니다
이것은 테스트입니다
아마 테스트
확실히 테스트

그리고 'not'을 사용하여 스크립트를 실행하면 1 줄과 4 줄을 완전히 삭제해야합니다.

나는 노력하고있다 :

PS C:\Users\Admin> (Get-Content "D:\Logs\co2.txt") | 
Foreach-Object {$_ -replace "3*Program*", ""} | 
Set-Content "D:\Logs\co2.txt"

그러나 그것은 전체 라인이 아니라 '프로그램'만을 대체합니다.

답변:


25

내가 할 일은 다음과 같습니다.

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt

Snark의 라인 은 동일하지만 모든 파일을 배열로로드하는 것으로 시작합니다. 이는 큰 파일의 메모리 측면에서 문제가 될 수 있습니다.


Out-File 대신 Set-Content를 사용하는 것이 좋습니다. 전자는 원시 데이터를 처리하고 문자열이나 형식 객체를 잘라 내지 않습니다.
JasonMArcher

@JasonMArcher 다음을 사용하여 예제를 게시 할 수 있습니까 Set-Content? 나는 그것이 Set-Content드롭 인 대체품 이라고 생각하지 않습니다 Out-File.
아이언 사무엘 맥린 장로

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Out-File은 기본적으로 Set-Content이지만 간단한 문자열 변환 대신 기본 형식을 통해 입력을 실행합니다.
JasonMArcher

나는 똑같은 문제가 있었고 당신은 내가 필요한 것의 99 %라고 대답했습니다. 마지막 문제는 $ variable이있는 루프에서 명령을 실행하고 있다는 것입니다 (이 예제에서는 'not'으로 대체). 문자열을 하드 코딩하면 완벽하게 작동합니다. 그러나 변수를 사용하면 아무것도하지 않습니다. 왜 그런지 알아? 나는 베어 변수를 모두 "quotes"에 넣었습니다
Stephen R

이 줄의 텍스트 를 대체 하기 위해 이것을 어떻게 수정할 수 있습니까?
Tom

7

이것은 작동합니다 :

(Get-Content "D:\Logs\co2.txt") -notmatch "not" | Out-File "D:\Logs\co2.txt"

True라는 두 번째 파일에서 한 줄만 반환합니다.

수정 : 두 번째 파일에서 'True'로 구성된 한 줄만 반환합니다. "Foreach-Object {$ _"가 없어서 한 줄에 한 번씩 실행됩니까? 편집 : 실제로 실제로는 관련이 없습니다. 내가 정리하고자하는 파일을 지 웠습니다. 어쨌든 도움을 주셔서 감사하지만, 앞으로 올바른 명령이 무엇인지 궁금해서 앞으로도 그렇게 할 수 있습니까?

1
위의 4 가지 테스트 라인에서 작동합니다.
Snark

2
원본 파일을 덮어 쓰지 않을 것입니다!
user33788

3
동의했지만 원래 포스터에서 사용한 것과 동일한 파일 이름을 사용하여 답을 더 쉽게 만들었습니다. 그는 입력과 출력 모두에 co2.txt를 사용했습니다.
Snark

0

-notmatch 옵션과 함께 'Select-String'을 사용할 수도 있습니다.

Select-String 'not' .\input.txt -notmatch | % {$_.Line} | set-content output.txt

0

방금이 작업을 수행하고 다음을 생각해 냈습니다.

$InServerName = 'SomeServerNameorIPAddress'
$InFilePath = '\Sharename\SomePath\'
$InFileName = 'Filename.ext'

$OutServerName = 'SomeServerNameorIPAddress'
$OutFilePath = '\Sharename\SomePath\'
$OutFileName = 'Filename.out'

$InFile = -join('\\',$InServerName,$InFilePath,$InFilename)
$OutFile = -join('\\',$OutServerName,$OutFilePath,$OutFilename)
$FindStr = 'some string to match on'
$CompareStr = [scriptblock]::Create($FindStr)
$CompareStr
Get-Content $InFile | Where-Object {$_ -notmatch $CompareStr} | Set-Content $OutFile
Get-Content $OutFile

스크립트 블록을 사용하는 'Where-Object'(중괄호로 표시)는 스크립트 블록 생성 이벤트에서 변수를 선언해야합니다.

$CompareStr = [scriptblock]::Create($FindStr)

선.

이러한 방식으로 함수를 구성함으로써, 함수를 생성하고, 부분적으로 일치하는 텍스트 문자열을 전달하고, 전달 된 값으로 스크립트 블록 생성을 수행하고, 올바르게 작동하게 할 수 있습니다.

위의 답변은 변수 내에서 바꿀 값을 전달하는 방법을 올바르게 설명하지 않습니다.


이것이 Snark의 (훨씬 더 간결한) 답변 보다 더 낫다는 것을 설명 할 수 있습니까 ? 의견에 응답하지 마십시오. 더 명확하고 완전하게 답변을 편집 하십시오.
Scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.