Change text in file with data from an other file and write out to screen - powershell

I would start with I was looking for answers but I could not find one.
The code is this but it reads in 1 line from the data.txt and after that all lines in message.txt.
The message.txt contains strings and data.txt has these separeted with ';' like this:
Josh Adams;NYC 5th Avenue;18:25
Peter Nordmann;NCY 5th Avenue;20:00
...
foreach ($dataLine in Get-Content .\data.txt){
$data = $dataLine -split ';'
foreach($line in Get-Content .\message.txt){
$line.replace('<name>', $data[0])
$line.replace('<place>', $data[1])
$line.replace('<time>', $data[2])
}
Write-Output $line
}

Just capture your searched text content to a variable, use that variable content to write to the new or the other file, using the normal built-in cmdlet(s)...
Add-Content
or
Out-File
.. using the append options.
Lastly, there are multiple ways to save content to a variable, for use elsewhere and output to the screen.
3 ways to store and display PowerShell Variable simultaneously
# Using -OutVariable parameter
Get-Process a* -OutVariable process
# PowerShell Variable squeezing
($process = Get-Process a*)
# Using Tee-Object Cmdlet
Get-Process a* | Tee-Object -Variable p

Related

Powershell remove lines containing the incorrect number of words

Can this be done in easily or at all in powershell?
How would one remove all lines from "test.txt" that do not contain exactly 24 words
This is not too hard in PowerShell.
Something like below should do it:
# read the file and use Where-Object to capture only those lines that have 24 words exactly.
# the regex -split uses '\W+', meaning to split each line on (at least one) Non-Word character.
$result = Get-Content -Path 'D:\test.txt' | Where-Object { ($_ -split '\W+').Count -eq 24 }
# output on screen
$result
# write output to new file
$result | Out-File -FilePath 'D:\test24.txt' -Force

Powershell Copy in certain line

I want to copy the content of my text file test1.txt in the line 52 of my second text file test2.txt.
To copy I use the following commands:
$a=Get-Content "C:\Users\Administrator\Destop\test1.txt"
"$a"|Out-File "C:\Users\Administrator\Desktop\test2.txt" -Append
But how can I define a specific line?
And how to overwrite when there is something?
The Get-Content cmdlet basically returns a object array thus you can use some array range operators:
$a = Get-Content "C:\Users\Administrator\Destop\test1.txt"
$b = Get-Content "C:\Users\Administrator\Destop\test2.txt"
#($b[0 .. 51], $a) | out-File "C:\Users\Administrator\Desktop\test2.txt"

Find group of words in a text file and extract the line to new text file

txt contains word "hi" "hello" "aloha" as per below
hi
hello
aloha
And I have one more file abc.txt which contains many words including the above 3 words. Now I developed a PowerShell script to search the words in abc.txt and extract the line containing the words to a new file done.txt. I use
-match command to find the word.
How to use the file ref.txt which contains the words for the finding, instead of declare the words in coding?
I would like to develop it in cmd.exe instead of PowerShell.
$source = "C:\temp\abc.txt"
$destination = "C:\temp\done.txt"
$hits = select-string -Path $source -SimpleMatch "hi","hello","aloha"
$filecontents = get-content $source
foreach($hit in $hits)
{
$filecontents[$hit.linenumber-1]| out-file -append $destination
"" |out-file -append $destination
}
This should do the batch trick:
findstr /G:ref.txt abc.txt >> done.txt
This would print all lines containing the stings in ref.txt in abc.txt to done.txt
Have I understood you question correctly?
To cover the PowerShell aspect of this question...
To get the patterns you want from file is rather easy since Select-String supports strings arrays for the -Pattern parameter. In its simplest form you could just do something like this
$patterns = Get-Content c:\temp\ref.txt | Where-Object{$_}
$hits = Select-String c:\temp\test.txt -Pattern $patterns -SimpleMatch
Your file contained a blank which I was not sure was on purpose or not. I used Where-Object{$_} to filter that out just in case. Then just pass that string array $patterns to the parameter -Pattern.
The rest of your code after that could use a little tune up. There is no need to read the source file in a second time just to output the matches again. Your output is just the matching line with a newline following.
$patterns = Get-Content c:\temp\ref.txt | Where-Object{$_}
$results = Select-String c:\temp\test.txt -Pattern $patterns -SimpleMatch
$results.Line | ForEach-Object{"$_`r`n"} | Set-Content C:\temp\out.txt
Probably not the best way to get the desired output but it should work regardless.

Powershell. Writing out lines based on string within the file

I'm looking for a way to export all lines from within a text file where part of the line matches a certain string. The string is actually the first 4 bytes of the file and I'd like to keep the command to only checking those bytes; not the entire row. I want to write the entire row. How would I go about this?
I am using Windows only and don't have the option to use many other tools that might do this.
Thanks in advance for any help.
Do you want to perform a simple "grep"? Then try this
select-string .\test.txt -pattern "\Athat" | foreach {$_.Line}
or this (very similar regex), also writes to an outfile
select-string .\test.txt -pattern "^that" | foreach {$_.Line} | out-file -filepath out.txt
This assumes that you want to search for a 4-byte string "that" at the beginning of the string , or beginning of the line, respectively.
Something like the following Powershell function should work for you:
function Get-Lines {
[cmdletbinding()]
param(
[string]$filename,
[string]$prefix
)
if( Test-Path -Path $filename -PathType Leaf -ErrorAction SilentlyContinue ) {
# filename exists, and is a file
$lines = Get-Content $filename
foreach ( $line in $lines ) {
if ( $line -like "$prefix*" ) {
$line
}
}
}
}
To use it, assuming you save it as get-lines.ps1, you would load the function into memory with:
. .\get-lines.ps1
and then to use it, you could search for all lines starting with "DATA" with something like:
get-lines -filename C:\Files\Datafile\testfile.dat -prefix "DATA"
If you need to save it to another file for viewing later, you could do something like:
get-lines -filename C:\Files\Datafile\testfile.dat -prefix "DATA" | out-file -FilePath results.txt
Or, if I were more awake, you could ignore the script above, use a simpler solution such as the following one-liner:
get-content -path C:\Files\Datafile\testfile.dat | select-string -Pattern "^DATA"
Which just uses the ^ regex character to make sure it's only looking for "DATA" at the beginning of each line.
To get all the lines from c:\somedir\somefile.txt that begin with 'abcd' :
(get-content c:\somedir\somefile.txt) -like 'abcd*'
provided c:\somedir\somefile.txt is not an unusually large (hundreds of MB) file. For that situation:
get-content c:\somedir\somefile.txt -readcount 1000 |
foreach {$_ -like 'abcd*'}

Loading a PowerShell hashtable from a file?

I've got a file containing some data in PowerShell Object Notation:
#{ X = 'x'; Y = 'y' }
I'd like to load this into a variable from the file.
(I figured it out while putting together a repro)
PS> $content = ( Get-Content .\foo.pson | Out-String )
PS> $data = ( Invoke-Expression $content )
Get-Content returns an array with the lines in the file; the Out-String is used to join them together.
Invoke-Expression then runs the script, and the result is captured. This is open to injection attacks, but that's OK in my specific case.
Or, if you prefer your PowerShell terse:
PS> $data = gc .\foo.pson | Out-String | iex
(I can't find a shorter form of Out-String)
I've used ConvertFrom-StringData. If you want to use this approach you'll need to change the way you store key/value pairs with each on its own line and no quotes:
#Contents of test.txt
X = x
Y = y
get-content .\test.txt | ConvertFrom-StringData
Name Value
---- -----
X x
Y y
ConvertFrom-StringData is a built-in cmdlet. I created corresponding ConvertTo-StringData function available here http://poshcode.org/1986
I ran into trouble using ConvertFrom-StringData as #Chad suggested. If you do:
$hash = get-content .\test.txt | ConvertFrom-StringData
I found I had an object array rather than a hash table. In fact, it appears that I had an array of hash tables, each with one entry. I confirmed with a:
$hash.GetType()
It looks like you need to join each line of the slurped input file to ensure that it forms a single string for ConvertFrom..'s use:
$hash = ((get-content .\test.txt) -join '`n') | ConvertFrom-StringData
If you can give this file the extension .ps1, say, data.ps1 then it cannot be simpler than this code:
$data = <path>\data.ps1
Starting from PowerShell 5.0 you have
Import-PowerShellDataFile
Which imports values from a .psd1-file. So the only thing you have to do is rename your file to *.psd1
Official help is here.
This is an older post but, this is sort of a twist on your accepted solution and perhaps slightly more "safe", keep in mind un-trusted files.
From your notes, you have a file that contains a hashtable using Powershell syntax. Given that constraint, you can import it directly:
$HashPath = ".\foo.pson"
# input file contents
$filecontent = Get-Content -Path $HashPath -Raw -ErrorAction Stop
# put the file in a script block
$scriptBlock = [scriptblock]::Create( $filecontent )
#check that the file contains no other Powershell commands
$scriptBlock.CheckRestrictedLanguage( $allowedCommands, $allowedVariables, $true )
#execute it to create the hashtable
$hashtable = ( & $scriptBlock )
Note on the $scriptBlock.CheckRestrictedLanguage you could replace that with
$scriptBlock.CheckRestrictedLanguage([string[]]#(), [string[]]#(), $false)
Use an empty list of strings so we do not allow any Powershell commands. When importing a hashtable, this is exactly what we want. That last one is allowEnvironmentVariables so we restrict that in this example with $false.
Side note, a Powershell module (psd1 file) is just a hashtable so this concept may help you to also pull in script blocks or other things.
Reference: https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.scriptblock.checkrestrictedlanguage?view=powershellsdk-1.1.0