How to stop Get-Content -wait after I find a particular line in the text file using powershell? Exit a pipeline on demand

£可爱£侵袭症+ 提交于 2020-03-11 14:52:34

问题


I am using this below script in Powershell (Version is 5.1):

Get-Content -Path path\to\text\file\to\be\read.txt -Wait

Now this continues to read even after the file is getting no update. How can I stop after I find particular line in the text file? Is there any other way to stop this on condition?


回答1:


You can pipe the output and use foreach to check each line, if the line equals a certain string you can use break to stop the command:

Get-Content path\to\text\file\to\be\read.txt -wait | % {$_ ; if($_ -eq "yourkeyword") {break}}

For example, if you run the command above and do the following in another shell:

"yourkeyword" | Out-File path\to\text\file\to\be\read.txt -Append

The Get-Content displays the new line and stops.


Explanation:

| % - foreach line that is in the file or gets added to the file while the function runs

$_; - first write out the line of the foreach then do another command

if($_ -eq "yourkeyword") {break} - if the line of the foreach is equal to the keyword/line you want, stop the Get-Content




回答2:


tl;dr

do {
  Get-Content -Path path\to\text\file\to\be\read.txt -Wait | ForEach-Object {
    # Pass the input line through.
    $_
    # Exit once the string of interest is found.
    if ($_ -match 'patternOfInterest') { break } 
  }
} while ($false) # dummy loop so that `break` can be used.

# NOTE: Without the dummy `do` loop, this code would not be reached.
'Line of interest found.'

Note that the -match operator performs substring matching using regexes (about_Regular_Expressions).

Read on for why the dummy do loop is needed.


Paxz's answer is on the right track, but it tries to use break (in isolation) to exit the pipeline, which (typically) terminates the whole script (if you submit the pipeline as a single command interactively, you may not notice).

break / continue are designed to exit / continue loops (for, foreach, do, while, and switch statements[1]), not pipelines.

As of PowerShell [Core] 7.0, there is no direct way to exit a pipeline prematurely, though adding this feature is the subject of this long-standing feature request on GitHub; currently, only direct use of Select-Object with -First can exit a pipeline prematurely, through use of non-public exception; while return can be used in a ForEach-Object script block, it only exits the current script-block invocation while continuing to process additional pipeline input.

If you use break or continue, PowerShell will look for any enclosing loop and if there is none, the script as a whole exits.

However, if you wrap a dummy loop around your pipeline[2], as shown above - whose sole purpose is to provide something for break to break out of - execution continues, as (usually) desired.

Caveat:

break / continue (and throw) have an important side effect: they do not give the other commands participating in the pipeline a chance to exit normally; that is, their end blocks / EndProcessing() methods are not called, which can be problematic in two respects:

  • Cmdlets that need to clean up (dispose of) temporarily held resources do not get to clean up.

  • Aggregating cmdlets - those that of necessity collect all input before being able to produce output - never get to produce output; here's a simple example:

PS> do { 5..1 | % { $_; if ($_ -eq 3) { break } } | Sort-Object } while ($false)
# !! NO OUTPUT, because Sort-Object's EndProcessing() method was never called.

[1] When you examine a single value with a switch statement, break exits the statement, as you would expect. If an array (a collection) of values is being processed, break too exits the statement immediately, without processing further elements in the array; continue, by contrast, continues processing with the next element.

[2] Another option is to use throw to generate a script-terminating error that you catch by enclosing the pipeline in a try / catch statement, as shown in this answer. However, this has the side effect of recording an entry in the automatic $Error collection, even though conceptually no actual error occurred.



来源:https://stackoverflow.com/questions/51981048/how-to-stop-get-content-wait-after-i-find-a-particular-line-in-the-text-file-us

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!