3

I have the following PowerShell script

$var = 'abcd'
echo $($var):123:zzz > test.txt

After execution, the content of test.txt becomes

abcd
:123:zzz

How can I avoid newline after abcd?

I mean I want the content of test.txt to be

abcd:123:zzz

How can I do this?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Brian
  • 12,145
  • 20
  • 90
  • 153
  • `'$($var):123:zzz' > test.txt` or "$var`:wetwet:ew" > test.txt – 4c74356b41 Jan 25 '17 at 08:50
  • 1
    I found that `"$($var):123:zzz" > test.txt` works for me. – Brian Jan 25 '17 at 08:54
  • @Seth: The original question title was a bit ambiguous; this question is _not_ about omitting a trailing newline from the output. To your point: `Write-Host` output cannot be redirected on PSv4-. In PSv5+, `Out-File` and `Set-Content` / `Add-Content` support `-NoNewline` as well. – mklement0 Jan 25 '17 at 17:49

3 Answers3

4

echo is an alias for the Write-Output cmdlet which is not necessary here at all. Just put the desired ouput into the pipeline and pipe it to the Set-Content cmdlet:

"$($var):123:zzz" | Set-Content -Path 'test.txt' -Encoding Unicode

Now, if you want to append another string to the file, use the Add-Content cmdlet:

"anotherLine" | Add-Content test.txt -Encoding Unicode
Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
1

Martin Brandl's helpful answer bypasses your problem with a solution that is preferable anyway (no need for Write-Output a.k.a echo).
This answer explains the problem with your approach.

tl;dr

  • Use double quotes:

    • echo "$($var):123:zzz" > test.txt
  • Simplified (no need for echo):

    • "$($var):123:zzz" > test.txt
  • Simplest (note the {}, which are needed to disambiguate the variable name):

    • "${var}:123:zzz" > test.txt
    • "$var`:123:zzz" > test.txt would work too (escaping the :)

Your specific problem is that $($var):123:zzz is parsed as 2 arguments, due to not being enclosed in ".

In other words: The following 2 statements are equivalent:

echo $($var):123:zzz

echo $($var) :123:zzz    

Both yield the following (wether in the console or when redirected to a file), because Write-Output (that echo is an alias for) writes its (stringified) arguments separated by a line break:

abcd
:123:zzz

Since you're passing $($var):123:zzz as an argument to the echo (Write-Output) command, it is parsed in argument mode.

In argument mode, an unquoted subexpression-operator expression such as $($var) at the start of a token is always treated as a separate argument, even if followed directly by more characters.

This answer of mine has more information about how PowerShell parses unquoted tokens in argument mode.

By contrast, double-quoting (enclosing the token in "...") ensures parsing as a single argument (though note that the subexpression will then be stringified first).

Thus, this command would work:

echo "$($var):123:zzz" > test.txt

Or, more simply, given that PowerShell outputs an expression's result by default (Write-Output is usually not needed):

"$($var):123:zzz" > test.txt

Note that while double-quoted strings are used in both commands, the latter command is technically parsed in expression mode (which is PowerShell's other, programming language-like parsing mode), because the command line starts with a ".

Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

If you are trying to add ":123:zzz" to the end of $var you can do this as well;

$var = 'abcd'
echo ($var+':123:zzz') > test.txt

or if you want to add a new line (append) add a second ">";

$var = 'abcd'
echo ($var+':123:zzz') >> test.txt