I'm using the following PowerShell command:
dir -r -include *.log | Select-String "Some pattern" | Out-File .\findings.out
If I open the findings.out file the "redirected" loglines include additional line breaks, that were not included in the original logfiles, e.g.:
Original logline:
xxxx.log:3977:2016-05-03T07:39:13.847+02:00; INFO ; hello world
Logline findings.out:
xxx.log:3977:2016-05-03T07:
39:13.847+02:00; INFO ;
hello world
Any hints?
Please consider the following:
$File = "$env:TEMP\test.txt"
All content on one line because the whole string is now quoted between ''' single quotes (or double quotes '"'):
'xxx.log:3977:2016-05-03T07:39:13.847+02:00; INFO ; hello world' | Out-File $File
Only 'hello world' is in the file:
'xxx.log:3977:2016-05-03T07:39:13.847+02:00'; 'INFO'; 'hello world' | Out-File $File
Because PowerShell sees the following:
Write-Output 'xxx.log:3977:2016-05-03T07:39:13.847+02:00'
Write-Output 'INFO'
Write-Output 'hello world' | Out-File $File
As you can see, only the last line is written to the CmdLet Out-File.
The last two statements are the same. The semicolon ';' is a PowerShell code seperator. So it's the same if you write it on multiple lines without the semicolon or on one line with semicolons between the strings
Related
I have been wondering some time how to add property to end of the properties file from powershell script included to batch file. Example is in the else branch. It seems that single quotes are causing the problem but I am not aware how to get rid of them or how to add the new line right way. Don't mind the other parts of the script.
powershell -Command "&{"^
"$file = 'conf\my.properties';"^
"$regex = '(my.boolean.property=(?i)(true|false))';"^
"$search = (Get-Content $file | Select-String -Pattern
'my.boolean.property').Matches.Success;"^
"if($search){ (Get-Content $file) -replace $regex, 'my.boolean.property=false' | Set-
Content $file; }"^
"else { Add-Content $file '`nmy.boolean.property=false' };"^
"}"
Two options come to mind that don't require double-quotes:
"else { Add-Content $file ([Environment]::NewLine + 'my.boolean.property=false') };"^
This will grab the OS-default newline sequence from the [Environment] type and prefix the string with it.
Alternatively, let Add-Content add an empty newline by piping an extra empty string to it:
"else { '','my.boolean.property=false' | Add-Content $file };"^
I need to search for a term in a file and display an index in the search results so that referencing is easy.
The command in bash would be:
cat <file> | grep 'Table: ' | cat -n
What I have so far in Powershell:
Get-Content <file> | Select-String 'Table: ' | Select-Object -Property LineNumber, Line
Unfortunately, I didn't realize that LineNumber gives the actual line in the file and not the index in the results list.
How can I translate the bash command into its Powershell equivalent?
Indeed, the .Line property of the objects output by Select-Object indicates the line number of each match in a given input file.
PowerShell has no direct equivalent of cat -n (prepending a 1-based index to all input lines on output), but it's not hard to roll your own using the ForEach-Object cmdlet:
$i = 0
Get-Content file.txt | Select-String 'Table: ' | ForEach-Object {
"{0,6}`t{1}" -f ++$i, $_.Line
}
The above uses -f, the format operator, to left-space-pad to 6 characters (,6) the first RHS operand ({0}), which is the (incremented) index, ++$i, followed by a tab character (`t) and the second RHS operand ({1}), which is the input line at hand ($_.Line).
Just use WSL:
bash -c "cat <file> | grep 'Table: ' | cat -n"
This will run the bash code in powershell. For a true powershell option you could do this:
foreach ($line in $(Get-Content -Path <filepath> | Select-String 'Table: ')){
$count++
echo "$count $line"
}
This is part of the PowerShell script I am working on:
Write-Host $configJson.myVal
(Get-Content .\config.js) -replace "S=''", "S='$configJson.myVal';" | Set-Content .\out.js
The Write-Host part correctly displays the value in $configJson.myVal.
But when I run the second statement, the value that is put in the file is: System.Collections.Generic.Dictionary'2[System.String,System.Object].deployedBaseUrl
How can I change the second command so that the value that is output on the Write-Host line is also put into the file for my replace command?
I would use a format string:
Write-Host $configJson.myVal
(Get-Content .\config.js) -replace "S=''", ("S='{0}';" -f $configJson.myVal) | Set-Content .\out.js
When running the following code:
$txt = Get-Content file1.txt
$a = #"
-- file start --
$txt
-- file end --
"#
$a
All new lines are removed from the file's contents, but just running
$txt
prints out the file without stripping the new lines.
Any idea how to get it to work as desired using the here-string?
Thanks!
If you put an array in a string it will be expanded with $OFS (or a space if $OFS is $null) between the items. You can see the same effect with either
"$txt"
''+$txt
and a few others. You can set $OFS="`r`n" which would change the space with which they are joined to a line break.
You could also change the Get-Content at the start to either
$txt = Get-Content file1.txt | Out-String
$txt = [IO.File]::ReadAllText((Join-Path $pwd file1.txt))
Pipe $txt to Out-String inside a sub-expression.
$a = #"
-- file start --
$($txt | Out-String)
-- file end --
"#
I'm looking for a script, doesn't have to be in PS but must run under Windows, that converts a one column text file like below
abc
def
ghi
into
'abc',
'def',
'ghi'
I'm currently making this change in Excel using =concatenate, but a script would be better.
Use can use a regular expression to insert characters at beginning and end.
get-content ./myonlinecolumn.txt | foreach {$_ -replace "^","'" -replace "`$","',"}
Or you could use the format operator -f:
get-content ./myonlinecolumn.txt | foreach {"'{0}'," -f $_ }
Its a bit more work to remove the last trailing comma, but this also possible
$a = get-content ./myonlinecolumn.txt
get-content ./myonlinecolumn.txt | foreach { if ($_.readcount -lt $a.count) {"'{0}'," -f $_ } else {"'{0}'" -f $_ }}
My first idea was similar to what Chad already wrote, that is a check on the line number. So I've tried a different solution. Not very nice but I post it too :)
((gc c:\before.txt | % {"'"+$_+"'"} ) -join ",*").split("*") | out-file c:\after.txt
You can just use
(gc myfile | %{"'$_'"}) -join ',
'
or, if you love escapes:
(gc myfile | %{"'$_'"}) -join ",`n"
This loads the file into an array of strings (Get-Content), then processes each string by putting it into single quotes. (Use `"'$($_.Trim())'" if you need to trim whitespace, too). Then the lines are joined with a comma and line break (those can be embedded directly into strings).
If your values can contain single quotes (which need to be escaped) it's trivial to stick that in there, too:
(gc myfile | %{"'$($_.Trim() -replace "'","''")'"}) -join ",`n"