2

I am trying to search two strings in any two consecutive lines and need help.

Two search strings are "Airport" and "Rate" and sample Input file is described below :

Content of Input file :

1. Airport
2. Rate
3. Some text
4. Some more text
5. Airport
6. Some text

Desired Output :

1. Airport
2. Rate

P.S. Airport keyword in 5. is not in desired output since 4. and 6. doesn't have Rate keyword.

This is how I have get it so far :

PS> get-content "c:\Inputfile.txt" | select-string "Airport" -context 1 | s
elect-string "Rate" > c:\airportrate.txt


Thanks.
Powershel
  • 615
  • 4
  • 11
  • 18

3 Answers3

2

Using V3:

$Text = Get-Content "c:\Inputfile.txt" -Raw
[regex]$regex = '(?m)(^\d+\.\sAirport.*?\n\d+\.\sRate.*?)'
$regex.Matches($Text).value

From get-help get-content (V3)

-Raw Ignores newline characters and returns the entire contents of a file in one string. By default, the contents of a file is returned as a array of strings that is delimited by the newline character.

Raw is a dynamic parameter that the FileSystem provider adds to the Get-Content cmdlet. This parameter works only in file system drives.

This parameter is introduced in Windows PowerShell 3.0.

mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • `-Raw`? Not sure where you're getting that from, that results in `A parameter cannot be found that matches 'Raw'.` Doesn't exist in V3.0 documentation either: http://technet.microsoft.com/en-us/library/hh849787(v=wps.620).aspx – tnw Oct 25 '13 at 13:22
  • It works for me, and has since I installed V3. I believe it's not included in the documentation in your link because it's provider specific. – mjolinor Oct 25 '13 at 13:37
  • OK, removed downvote. Have you tested this though? From your documentation: "-Raw **Ignores newline characters**" which are pretty critical to your regex. – tnw Oct 25 '13 at 13:43
  • Yes, I tested it. When it says it ignores newline characters, it means it doesn't use them as delimiters. It simply returns the file as a single string with the newlines embedded. – mjolinor Oct 25 '13 at 13:50
1

Try something like this, I've tested this on your input and got the correct output.

$reader = [System.IO.File]::OpenText("c:\Inputfile.txt")
$prevLine = ""
try {
    for(;;) {
        $line = $reader.ReadLine()
        if ($prevLine -ne "") 
        {
            if ($line -Match "Rate") 
            { 
                if ($prevLine -Match "Airport")
                {
                    $prevLine
                    $line
                }
            }                
        }
        $prevLine = $line
    }
}
finally {
    $reader.Close()
}

Credit due: https://stackoverflow.com/a/4192419/770270

Community
  • 1
  • 1
tnw
  • 13,521
  • 15
  • 70
  • 111
1

Read the file content in chunks of two lines, cast each chunk to a string and test if it matches your criteria:

PS> Get-Content .\lines.txt -ReadCount 2 | Where-Object {"$_" -match 'Airport.*rate' }
1. Airport
2. Rate
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • Isn't that going to stop finding matches if there's ever an odd number of unmatched lines between the Airport + Rate pairs? – mjolinor Oct 25 '13 at 14:40
  • I don't think so as odd numbered lines will result in a last group of just one line in it and it will not match. – Shay Levy Oct 25 '13 at 14:59
  • If there's multiple sets in the file, and odd numbers of lines between two sets, you'll end up with Airport as the second element of one array, and Rate as the first element of the next. – mjolinor Oct 25 '13 at 15:09
  • This doesn't seem to work appropriately for me. As 'mjolinor' pointed out, it won't work if "Airport" happens to be at odd line number. – Powershel Oct 28 '13 at 08:21
  • I made this getting a clue from Shay post. PS > get-childitem -recurse -filter *.txt | select-string -pattern "Airport" -context 1 | Where -Object {"$_" -match "rate" } > c:\Airportrate.txt – Powershel Oct 29 '13 at 06:44