Remove spaces between delimiter - powershell

I have many Data Text file which need to fix the spacing issue,
for example:
Name | First Name | Second Name |Last Name
The Expected Output should be as below:
Name|First Name|Second Name|Last Name (This is I want to achieve)
When I use below script its gives its gives me output removing spaces between the sentence as well so can not use, any idea to fix this script:
Get-Content File.txt | ForEach-Object { $_ -replace ' ' } > trimfile.txt
Output:
Name|FirstName|SecondName|LastName (Wrong)

Here a solution using a positiv lookahead and lookbehind to avoid replacing the spaces inside your string:
Get-Content File.txt | ForEach-Object { $_ -replace '(?<=\|)\s+|\s+(?=\|)' } > trimfile.txt

Related

Read text file and check for value in a specific position and change when true

I need to loop through multiple text files and check for a $ value in position 7 on each line of text and replace it with an * when found. But ONLY when it is in position 7. I do not want to change it if it is found in other positions. This is as far as I have gotten. Any help would be greatly appreciated.
Get-ChildItem 'C:\*.txt' -Recurse |
foreach $line in Get-Content $_ {
$linePosition1to5 = $line.Substring(0,6)
$linePosition7 = $line.Substring(6,1)
$linePositionRest = $line.Substring(8)
if($linePosition7 = "$"){
$linePosition7 = "*"
}
$linePosition1to5 + $linePosition7 + $linePositionRest |
Set-Content $_
}
Is there something that doesn't work in your example, or just that all the nested substrings are annoying to work with?
I'd use regex for this one. e.g.
$Lines = Get-Content -Path "C:\examplefile.txt" -raw
$Lines -replace '(?m)(^.{6})\$', '$1*'
To explain the regex:
?m indicates that it's multiline, required because I used raw get-content rather than pulling an array. Array would work too, just needs a loop like you did.
^.{6} line start plus any 6 characters (capture group 1)
$ escaped dollar character
$1* Capture group 1 left as is, dollar replaced with *, anything else not captured and therefore left untouched.
Thanks for code and the explanation. I realized that I left out the -raw option and it did work. Putting it back in it seems to add a line to the end of each file. Unless you can think of reason why I shouldn't I was going to leave it out.
Get-ChildItem 'C:\TEST\*.txt' -Recurse | ForEach {
(Get-Content $_ | ForEach { $_ -replace '(?m)(^.{6})\$', '$1*'}) |
Set-Content $_
}

Merge Text Files and Prepend Filename and Line Number - Powershell

I've been trying to adapt the answer to this question: powershell - concatenate N text files and prepend filename to each line
My desired output based on an example of 2 .txt files:
First.txt
lines of
data
Second.txt
more lines
of
data
Output.txt
First1 lines of
First2 data
Second1 more lines
Second2 of
Second3 data
Based on the most similar question I could find the following answer:
Select-String '^' *.txt >output.txt
Would give:
C:\A\Filepath\First.txt:1:lines of
C:\A\Filepath\First.txt:2:data
C:\A\Filepath\Second.txt:1:more lines
C:\A\Filepath\Second.txt:2:of
C:\A\Filepath\Second.txt:3:data
So I was hoping to use -replace to remove the filepath, keep the file name (but remove .txt:), keep the line number (but replace the final : with a space) and keep the text from the line.
Any help would be appreciated reaching the desired output.txt. Thanks
Not beautiful but this is one approach.
Get-ChildItem *.txt |
%{$FILENAME=$_.BaseName;$COUNT=1;get-content $_ |
%{"$FILENAME"+"$COUNT"+" " + "$_";$COUNT++}}|
Out-File Output.txt
The select-string approach is very interesting. The way I would go about it is to use Get-Content. The advantage there is that each line has a readcount property that represents the line number.
Get-ChildItem "C:\temp\*.file" | ForEach-Object{
$fileName = $_.BaseName
Get-content $_ | ForEach-Object{
"{0}{1} {2}" -f $fileName,$_.ReadCount,$_
}
} | Add-Content "C:\temp\output.txt"
Take each file and use Get-Content. With each line we process we send to the output stream a formatted line matching your desired output. No need to count the lines as $_.ReadCount already knows.
Select-String still works
You just need to manipulate the output to match what you want. Using Get-Member we can check the properties of what select-string returns to get our desired output.
Select-String '^' "c:\temp\*.txt" | ForEach-Object{
"{0}{1} {2}" -f $_.Filename,$_.LineNumber,$_.Line
} | Add-Content "C:\temp\output.txt"

Replace ^M with <space> in all lines of a file

I have a log file with ^M embedded throughout. I would like to replace the ^M with a single space.
I have tried variations on this:
(Get-Content C:\temp\send.log) | Foreach-Object {$_ -replace "^M", ' '} | Set-Content C:\temp\send.out
The output file contains a newline where each ^M had been, not at all what I was looking for...
The problem I am trying to solve involves examining the last $cnt lines of the file:
$new = Get-Content $fn | Select-Object -Last $cnt;
$new
When I display $new, the ^M are interpreted as CR/LF.
How can I remove/replace the ^M? Thanks for any pointers....
Sounds like ^M is not being replaced by your -replace method, it's likely the replace method is trying to replace capital letter M at the beginning of the string (^). Upon opening the file, ^M is then being interpreted as a carriage return.
Perhaps try replacing the carriage returns (^M) before displaying the contents:
(Get-Content C:\temp\send.log) |
Foreach-Object {$_ -replace "`r", ' '} |
Set-Content C:\temp\send.out
or
$new = Get-Content $fn | Select-Object -Last $cnt;
$new.replace("`r"," ")
Could this be as simple as escaping the ^ character? If you only need the last $count lines of the file you can use the -Tail parameter on Get-Content. Depending if you need to match ^M as case sensitive you might opt for -creplace instead of -replace.
Get-Content $inputfile -Tail $count | ForEach-Object { $_ -creplace '\^m',' ' } | Set-Content $outputfile
This isn't an answer, but since you asked for a few pointers, this might help set things straight.
Try this:
$new = Get-Content $fn | Select-Object -Last $cnt;
$new
$new.gettype()
$new[0].gettype()
I expect you're going to see that $new is an array of objects, and that $new[0] is a string. I'm going to suggest that $new[0] doesn't contain CR or LF or CRLF or anything like that. And I'm going to suggest that, when you ask for the display of $new in its entirety, what you are getting is each string ($new[0] followed by $new[1] ...) with CRLF inserted as a separator.
If I'm right, replacing CR or CRLF with space isn't going to do you any good at all. It's the CRLFs that are being inserted on output to a file that are preventing you from succeeding.
This is as far as I got towards solving your problem.

csv reformatting with powershell

I have a file cointaining a lot of lines in this format:
firstname ; lastname ; age ;
(it's a bit more complex but that's basically the file)
so the fields are of a fixed length, padded with spaces and with a semicolon in between the fields.
I would like to have it so:
firstname, lastname, age,
(commas and no fixed width)
I have replaced the commas with regexp but I would like to also trim the end of the strings. But I don't know how to do this.
The following is my start, but I can't manage to get a ".TrimEnd()" in there. I have also thought of trying a "-replace(" ", " ") but I can't integrate it in this expression:
Get-Content .\Bestand.txt | %{$data= [regex]::split($_, ';'); [string]:: join(',', $data)}
Can I get some information on how to achieve this?
I suggest you replace each occurrence of 'space;space' with a comma (assuming the replaced characters do not appear within a valid value), so the end result will look like:
firstname,lastname,age
Keeping it like the following is not a good idea cause now some of your headers (property names) start with a space:
"firstname, lastname, age,"
Give this a try (work on a copy of the file):
(Get-Content .\Bestand.txt) |
foreach {$_ -replace ' ; ',','} |
out-file .\Bestand.txt
Now it's easy to import and process the file with Import-Csv cmdlet.
The -replace operator takes a regular expression, which you can use to remove all leading and trailing spaces:
Get-Content .\Bestand.txt |
Foreach-Object { $_ -replace ' *; *',',' } |
Out-File .\Bestand.csv -Encoding OEM
Since you already create something CSV-ish, I'd go all the way and create proper CSV:
$cols = "firstname","lastname","age","rest"
Import-Csv "C:\input.txt" -Delimiter ";" -Header $cols | % {
foreach ($property in $_.PsObject.Properties) {
$property.Value = ([string]$property.Value).Trim()
}
$_
} | Export-Csv "C:\output.csv" -NoTypeInformation

PowerShell script to convert one-column CSV file

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"