Issue
Editor's note:
The macOS
sed
command below performs an in-place (-i ''
) string-substitution (string-replacement) operation on the given file, i.e. it transforms the file's existing content. The specific substitution shown,s/././g
, replaces all non-newline characters (regex metacharacter.
) with verbatim.
characters, so be careful when trying the command yourself.While the intended question may ultimately be a different one, as written the question is well-defined, and can be answered to show the full PowerShell equivalent of the
sed
command (a partial translation is in the question itself), notably including the in-place updating of the file.
I have a mac command and i need it to run on windows. I have no experience in mac whatsoever.
sed -i '' 's/././g' dist/index.html
After research i found that i should use
get-content path | %{$_ -replace 'expression','replace'}
but can't get it to work yet.
Solution
Note:
- The assumption is that
s/././g
in yoursed
command is just a example string substitution that you've chosen as a placeholder for real-world ones. What this example substitution does is to replace all characters other than newnlines (regex.
) with a verbatim.
Therefore, do not run the commands below as-is on your files, unless you're prepared to have their characters turn into.
The direct translation of your sed
command, which performs in-place updating of the input file, is (ForEach-Object
is the name of the cmdlet that the built-in %
alias refers to):
(Get-Content dist/index.html) |
ForEach-Object { $_ -replace '.', '.' } |
Set-Content dist/index.html -WhatIf
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
Or, more efficiently:
(Get-Content -ReadCount 0 dist/index.html) -replace '.', '.' | Set-Content dist/index.html -WhatIf
-ReadCount 0
reads the lines into a single array before outputting the result, instead of the default behavior of emitting each line one by one to the pipeline.
Or, even more efficiently, if line-by-line processing isn't required and the -replace
operation can be applied to the entire file content, using the -Raw
switch:
(Get-Content -Raw dist/index.html) -replace '.', '.' | Set-Content -NoNewLine dist/index.html -WhatIf
Note:
-replace
, the regular-expression-based string replacement operator uses the syntax<input> -replace <regex>, <replacement>
and invariably performs global replacements (as requested by theg
option in yoursed
command), i.e. replaces all matches it finds.- Unlike
sed
's regular expressions, however, PowerShell's are case-insensitive by default; to make them case-sensitive, use the-creplace
operator variant.
- Unlike
Note the required
(...)
around theGet-Content
call, which ensures that the file is read into memory in full and closed again first, which is the prerequisite for being able to rewrite the file withSet-Content
in the same pipeline.- Caveat: While unlikely, this approach can result in data loss, namely if the write operation that saves back to the input file gets interrupted.
You may need
-Encoding
withSet-Content
to ensure that the rewritten file uses the same character encoding as the original content -Get-Content
reads text files into .NET strings recognizing a variety of encodings, and no information is retained as to what encoding was encountered.Except with the
Get-Content -Raw
/Set-Content -NoNewLine
solution, which preserves the original newline format, the output file will use the platform-native newline format - CRLF (\r\n
) on Windows, LF (\n
) on Unix-like platforms - irrespective of which format the input file originally used.
Answered By - mklement0 Answer Checked By - Katrina (WPSolving Volunteer)