2

I have a text file that contains something like the following:

blah, blah, blah ...

Text : {string1, string2, string3,
        string4, string5, string6,}

blah, blah, blah ...

Text : {string7, string8, string9,
        string10, string11, string12,}

and I would like to merge only the lines between the braces into one line to look like this:

blah, blah, blah ...

Text : {string1, string2, string3, string4, string5, string6,}

blah, blah, blah ...

Text : {string7, string8, string9, string10, string11, string12,}

However, I don't want to apply the change to the entire text file because it contains other things. I would like to edit only the text between braces { ... }. I messed around with -join but couldn't get it to work. I have the following script which opens the file, makes changes, and output into another file:

gc input.txt | 

# Here I have several editing commands, like find/replace.
# It would be great if I could add the new change here.

sc output.txt

Thank you!

2 Answers 2

4

Try this:

$text = (Get-Content .\input.txt) -join "`r`n"
($text | Select-String '(?s)(?<=Text : \{)(.+?)(?=\})' -AllMatches).Matches | % {
        $text = $text.Replace($_.Value, ($_.Value -split "`r`n" | % { $_.Trim() }) -join " ")
}
$text | Set-Content output.txt

It trims away the extra spaces at the start and end of each line, and connects all lines with a space.

Sign up to request clarification or add additional context in comments.

3 Comments

This is applied to the entire text file. I would like to only apply it to the text between the braces as I said, if possible.
see updated answer. this is almost identical to your other question which is answered now also.
This is a different approach so I figured it's worth asking a new question. Your solution works for the first set of 'Text : {'. But then it also changes (trims and joins) everything after it. So it is not restricted to only the text between braces throughout the file. I edited the question for a better representation of what is inside the file. I really appreciate your help Graimer.
1

Jumbo shrimp in a can:

$testdata = @'
blah, blah, blah ...

Text : {string1, string2, string3,
        string4, string5, string6,}

blah, blah, blah ...

Text : {string7, string8, string9,
        string10, string11, string12,}
'@

$testfile = 'c:\testfiles\testfile.txt'
$testdata | sc $testfile
$text = [IO.File]::ReadAllText($testfile)

$regex = @'
(?ms)(Text\s*:\s\{[^}]+)\s*
\s*([^}]+)\s*
'@

$text -replace $regex,'$1 $2'

blah, blah, blah ...

Text : {string1, string2, string3, string4, string5, string6,}

blah, blah, blah ...

Text : {string7, string8, string9, string10, string11, string12,}

4 Comments

Nice solution, but this only support 2 lines. It should be dynamic.
Unless I've misread the question, that's the objective. It will match and replace those 2 lines anywhere in the text. I'll update the answer to be more demonstrative.
His file is actually this: stackoverflow.com/questions/14840632/… which has 3 lines. It's a log file or something, so I guess the "Text" part can be 1 line, 10 lines, changing from time to time
It'll match whatever is in that here-string (that's the "can"), and the jumbo shrimp option (?ms) means you can write it to match to multiple lines. A .+ will match through multiple lines. Putting the regex segments on separate lines in the here-string is implicitly adding ^ and $ anchors to that part of the regex.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.