Xóa toàn bộ dòng trong tệp văn bản dựa trên khớp chuỗi một phần với Windows PowerShell


22

Vì vậy, tôi có một số tệp văn bản lớn tôi cần sắp xếp và loại bỏ tất cả các dòng có chứa một từ khóa nhất định. Về cơ bản, nếu tôi có những dòng này:

Đây không phải là một bài kiểm tra
Đây là một bài kiểm tra
Có thể một bài kiểm tra
Chắc chắn không phải là một bài kiểm tra

Và tôi chạy tập lệnh với 'không', tôi cần xóa hoàn toàn dòng 1 và 4.

Tôi đã thử với:

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

nhưng nó chỉ thay thế 'Chương trình' chứ không phải toàn bộ dòng.

Câu trả lời:


25

Đây là những gì tôi sẽ làm:

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

Dòng của Snark cũng làm như vậy, nhưng nó bắt đầu bằng việc tải tất cả các tệp vào một mảng, điều này có thể gây ra vấn đề với các tệp lớn.


Tôi sẽ đề nghị bạn sử dụng Set-Content thay vì Out-File, các giao dịch trước đây trong dữ liệu thô và sẽ không cắt các chuỗi hoặc định dạng đối tượng.
JasonMArcher

@JasonMArcher Bạn có thể gửi một ví dụ bằng cách sử dụng Set-Content? Tôi không tin rằng đó Set-Contentlà một sự thay thế thả vào cho Out-File.
Iain Samuel McLean Elder

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Out-File về cơ bản là Set-Content, nhưng nó chạy đầu vào thông qua định dạng mặc định thay vì chuyển đổi chuỗi đơn giản.
JasonMArcher

Tôi đã có cùng một vấn đề và bạn trả lời là 99% những gì tôi cần. Vấn đề cuối cùng là tôi đang chạy lệnh trong một vòng lặp với biến $ (thay thế 'không' trong ví dụ của bạn). Nếu tôi cứng mã một chuỗi, nó hoạt động hoàn hảo; nhưng nếu tôi sử dụng một biến thì nó không làm gì cả. Bất cứ ý tưởng tại sao? Tôi đã thử cả hai biến trần và đưa nó vào "dấu ngoặc kép"
Stephen R

Làm thế nào điều này có thể được sửa đổi để thay thế văn bản trên những dòng đó
Tom

7

Điều này sẽ làm việc:

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

Điều này chỉ trả về một dòng duy nhất trong tệp thứ hai có tên True.

Sửa lỗi: Điều này chỉ trả về một dòng duy nhất trong tệp thứ hai bao gồm 'True'. Có lẽ nó thiếu "Foreach-Object {$ _" để nó chạy một lần trên mỗi dòng? Chỉnh sửa: Thực sự bây giờ nó không liên quan, nó đã xóa tập tin mà tôi hy vọng sẽ xóa. Dù sao cũng cảm ơn bạn đã giúp đỡ, nhưng tôi vẫn tò mò lệnh chính xác sẽ là gì để tôi có thể làm điều này trong tương lai?

1
Nó hoạt động với tôi với 4 dòng thử nghiệm của bạn ở trên.
Snark

2
sẽ không bao giờ ghi đè lên tập tin gốc!
dùng33788

3
đồng ý, nhưng tôi đã sử dụng cùng tên tệp như được sử dụng bởi người đăng ban đầu, để làm cho câu trả lời dễ dàng hơn. Ông đã sử dụng co2.txt cho cả đầu vào và đầu ra.
Snark

0

Bạn cũng có thể sử dụng 'Chọn chuỗi' với tùy chọn -notmatch:

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

0

Tôi chỉ cần làm việc này và đưa ra những điều sau đây:

$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

Chìa khóa là 'Đối tượng ở đâu' sử dụng khối tập lệnh (được biểu thị bằng dấu ngoặc nhọn) yêu cầu khai báo biến trong sự kiện tạo khối tập lệnh, do đó

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

hàng.

Bằng cách cấu trúc nó theo cách này, người ta có thể tạo một hàm, truyền cho nó một chuỗi văn bản để khớp một phần, thực hiện việc tạo khối tập lệnh với giá trị được truyền và làm cho nó hoạt động chính xác.

Các câu trả lời ở trên không giải thích chính xác làm thế nào để vượt qua giá trị được thay thế trong một biến.


Bạn có thể giải thích (rõ ràng hơn) làm thế nào tốt hơn câu trả lời của Snark (ngắn gọn hơn nhiều) không? Xin vui lòng không trả lời trong các ý kiến; chỉnh sửa câu trả lời của bạn để làm cho nó rõ ràng và đầy đủ hơn.
Scott
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.