Question:
I have a script I am running in Powershell, and I want to be able to put a line in my resulting text file output between the ccript name and the script content itself.
Currently, from the below, the line $str_msg = $file,[System.IO.File]::ReadAllText($file.FullName)
is what I need, but I need a line to separate $file
and the result of the next expression. How can I do this?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
foreach ($file in [System.IO.Directory]::GetFiles($sqldir,"*.sql", [System.IO.SearchOption]::AllDirectories)) { $file = [System.IO.FileInfo]::new($file); $Log.SetLogDir(""); $str_msg = $file,[System.IO.File]::ReadAllText($file.FullName); $Log.AddMsg($str_msg); Write-Output $str_msg; # ... } |
Answer:
$str_msg = $file,[System.IO.File]::ReadAllText($file.FullName)
doesn’t create a string, it creates a 2-element array ([object[]]
), composed of the$file
[System.IO.FileInfo]
instance, and the string with the contents of that file.- Presumably, the
.AddMsg()
method expects a single string, so PowerShell stringifies the array in order to convert it to a single string; PowerShell stringifies an array by concatenating the elements with a single space as the separator by default; e.g.:
[string] (1, 2)
yields'1 2'
.
Therefore, it’s best to compose $str_msg
as a string to begin with, with an explicit newline as the separator, e.g.:
1 2 |
$strMsg = "$file`r`n$([System.IO.File]::ReadAllText($file.FullName))" |
Note the use of escape sequence "
to produce a CRLF, the Windows-specific newline sequence; on Unix-like platforms, you’d use just r
n""`n"
(LF).
.NET offers a cross-platform abstraction, [Environment]::NewLine
, which returns the platform-appropriate newline sequence (which you could alternatively embed as $([Environment]::NewLine)
inside "..."
).
An alternative to string interpolation is to use -f
, the string-formatting operator, which is based on the .NET String.Format()
method:
1 2 3 4 |
$strMsg = '{0}{1}{2}' -f $file, [Environment]::NewLine, [System.IO.File]::ReadAllText($file.FullName) |