Delete the only occurrence of "(123456789)" anywhere in a text file including both open and close parenthesis
get-content "D:\testing.txt" | % {$_ -replace "(\d{9})",""} | Out-File D:\temp\out.txt
Your regex is incorrect -> try "\(\d{9}\)".
You can check your code via this statement:
'12 abc"(123456789)" 90 efg' -replace '"\(\d{9}\)"'
Output:
12 abc 90 efg
Above code is available only under this tio.run link.
Related
I have one table (.txt file) in this form:
Table: HHBB
Displayed Fields: 1 of 5 Fixed Columns: 4
-----------------------------------------------------------------------------
| |ID |NAME |Zähler |Obj |ID-RON |MANI |Felder |Nim
|----------------------------------------------------------------------------
| |007 |Kano |000001 |Lad |19283712 | |/HA |
| |007 |Bani |000002 |Bad |917391823 | |/LA |
I want to save this table into another .txt file but just want to skip the lines that match Table and Displayed Fields for example. What I tried:
If ([string]::IsNullOrWhitespace($tempInputRecord2) -or $_ -match "=|Table:|Displayed|----") {
continue
}
How can I do that?
And another question:
What is the best way to write the lines one by one into a new text file?
So you just want to remove the lines which start with Table: or Displayed Fields: and output results to a new file? Use Where-Object to filter lines, and Out-File to write them to the file:
Get-Content test.txt |
Where-Object { $_ -notlike "Table:*" -and $_ -notlike "Displayed Fields:*" } |
Out-File test2.txt
There are many ways for simple tasks:
If the header to skip occurs only once:
Get-Content test.txt|Select-Object -Skip 2|Set-Content test2.txt
A similar approach to yours with -notmatch and RegEx alternation
Get-Content test.txt|Where-Object {$_ -notmatch '^Table:|^Displayed Fields:'}|Set-Content test2.txt
When forcing a complete read in to memory by enclosing in parentheses you can write to the same file:
(Get-Content test.txt)|Select-Object -Skip 2|Set-Content test.txt
I have a text file with Name at position 0-10, phone at 11-20.
How can I replace a string at location 11 to contain all 9's?
I've been playing around with Get-Content and -replace to get familiar.
$path = "g:\test.txt"
(Get-Content $path) -replace "Name", "Forename" | Out-File $path
Example :
STARTDELIV|BA|BATCH PRINT |
INFORMAT01|email#address.com |
INFORMAT02|01021990|CRZWS|AA|2 |
INFORMAT03|Mr. John Doe|+00000 |
So say I would like to replace the name Mr. John Doe with X's , how would I prevent it replacing the same 10 bytes on every line
You could use the SubString method to get the 10 characters of the string starting from position 11:
$Path = "g:\test.txt"
$String = (Get-Content $Path)
$StringToReplace = $String.Substring(11,10)
And then use -Replace to replace that part of the string with all 9s (beware this assumes that string doesn't occur in that way anywhere else in the string):
$String -Replace $StringToReplace,('9'*$StringToReplace.Length)
Here's a shorter single line way to achieve the same result:
$String.Replace($String.Substring(11,10),'9'*10)
I've tried to parse own custom log files rows and I except to get some spesific rows which header value is involved querystring values and included spesific key-value
I spesified some example log file rows as below :
2016-01-04 14:07:06 192.168.1.0 - example.com GET MainPage a=2&b=20&c=12-10&d=apple
2016-01-04 14:07:07 192.168.1.0 - example.com GET Search x=2&y=20&c=56-32-12&d=orange
2016-01-04 14:07:08 192.168.1.0 - example.com GET ProdView r=1&b=20&c=24&d=orange
2016-01-04 14:09:38 192.168.1.0 - example.com GET ProdView a=2&b=20&c=1-23e&d=orange
What I want for my own powershell result
2016-01-04 14:07:08 192.168.1.0 - example.com GET ProdView r=1&b=20&c=24&d=orange
Output must show which querystring parameters contains c and it points just numeric value(it mustn't contains any '-' character)
My own query as below :
Import-Csv -Encoding UTF8 .\logs\x.log -header A,B,C,D,E,F,G,H -delimiter ' ' | where {$_.H -match "c"} | select-string H
But I've blocked when I attempt to parse querystring parameters
Best regards
You could use a regular expression to match the log entries where the query-string contains the information you describe - parameter c is present, has only numerical digits as its value:
$_.H -match '(^|&)c=\d+(&|$)'
# (^|&) either start-of-string or the character &
# c= the literal string "c="
# \d+ one or more digits
# ($|&) either end-of-string or the character &
in your example, you have double and triple spaces, but this example only works if there is just a single space.
Import-Csv -Encoding UTF8 .\logs\x.log -header A,B,C,D,E,F,G,H -delimiter ' ' | ? h -match 'c[^-]+(&|$)' | select -exp h
or maybe something like this:
gc .\logs\x.log | % {$($_ -replace ' +', ' ').trim().split(' ')[-1]} | ? {$_ -match 'c[^-]+(&|$)'}
I have a text file with 5 columns of text delimited by whitespace. For example:
10 45 5 23 78
89 3 56 12 56
999 4 67 93 5
Using PowerShell, how do I remove the rightmost two columns? The resulting file should be:
10 45 5
89 3 56
999 4 67
I can extract the individual items using the -split operator. But, the items appear on different lines and I do not see how I can get them back as 3 items per line.
And to make the question more generic (and helpful to others): How to use PowerShell to remove the data at multiple columns in the range [0,n-1] given an input that has lines with delimited data of n columns each?
Read the file content, convert it to a csv and select just the first 3 columns:
Import-Csv .\file.txt -Header col1,col2,col3,col4,col5 -Delimiter ' ' | Select-Object col1,col2,col3
If you want just the values (without a header):
Import-Csv .\file.txt -Header col1,col2,col3,col4,col5 -Delimiter ' ' | Select-Object col1,col2,col3 | Format-Table -HideTableHeaders -AutoSize
To save back the results to the file:
(Import-Csv .\file.txt -Header col1,col2,col3,col4,col5 -Delimiter ' ') | Foreach-Object { "{0} {1} {2}" -f $_.col1,$_.col2,$_.col3} | Out-File .\file.txt
UPDATE:
Just another option:
(Get-Content .\file.txt) | Foreach-Object { $_.split()[0..2] -join ' ' } | Out-File .\file.txt
One way is:
gc input.txt | %{[string]::join(" ",$_.split()[0..2]) } | out-file output.txt
(replace 2 by n-1)
Here is the generic solution:
param
(
# Input data file
[string]$Path = 'data.txt',
# Columns to be removed, any order, dupes are allowed
[int[]]$Remove = (4, 3, 4, 3)
)
# sort indexes descending and remove dupes
$Remove = $Remove | Sort-Object -Unique -Descending
# read input lines
Get-Content $Path | .{process{
# split and add to ArrayList which allows to remove items
$list = [Collections.ArrayList]($_ -split '\s')
# remove data at the indexes (from tail to head due to descending order)
foreach($i in $Remove) {
$list.RemoveAt($i)
}
# join and output
$list -join ' '
}}
I have a bunch of IIS logs and powershell 2.0.
Currently i'm using the following command to find some info out about them (where 'crossdomain' occurs in them):
dir -r -i *.log | select-string "crossdomain" | Select-Object | export-csv test.csv
This then gives me some data like so:
TRUE 1132740 2011-06-09 11:13:49 W3SVC322653822 myserver-WEB1 1.1.1.1 GET /crossdomain.xml - 80 - 1.1.1.1 HTTP/1.1 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+6.0;+Trident/4.0;+GTB6.5;+SLCC1;+.NET+CLR+2.0.50727;+Media+Center+PC+5.0;+.NET+CLR+3.5.30729;+.NET+CLR+3.0.30618) WT_FPC=id=82.40.25.58-3980883472.30062468:lv=1307614413232:ss=1307614405277;+__utma=151217894.932228880.1307618019.1307618019.1307618019.1;+__utmz=151217894.1307618019.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);+myserverVISITOR=eyJzaVZpc2l0VHJhY2tpbmcxIjpbeyJWSVNJVERBVEUiOiJNYXksIDEzIDIwMTEgMDY6NTc6NTAiLCJTVEFOREFSRElURU1JRCI6NjQ0MTkzLjB9LHsiVklTSVREQVRFIjoiTWF5LCAxMyAyMDExIDE1OjU0OjMyIiwiU1RBTkRBUkRJVEVNSUQiOjYwMzc4OC4wfSx7IlZJU0lUREFURSI6Ik1heSwgMTUgMjAxMSAxMzo0MDoxNCIsIlNUQU5EQVJESVRFTUlEIjo2NDQxOTUuMH0seyJWSVNJVERBVEUiOiJNYXksIDE1IDIwMTEgMTQ6MDE6NDEiLCJTVEFOREFSRElURU1JRCI6NjQ0MTkyLjB9LHsiVklTSVREQVRFIjoiTWF5LCAxNSAyMDExIDE0OjAzOjIyIiwiU1RBTkRBUkRJVEVNSUQiOjY0NDIxMC4wfSx7IlZJU0lUREFURSI6Ik1heSwgMTUgMjAxMSAxNDoyMTozMiIsIlNUQU5EQVJESVRFTUlEIjo2NDQ2MjAuMH0seyJWSVNJVERBVEUiOiJNYXksIDIyIDIwMTEgMDk6MTM6NTIiLCJTVEFOREFSRElURU1JRCI6NjI5NzYyLjB9LHsiVklTSVREQVRFIjoiSnVuZSwgMDcgMjAxMSAxMTo1MjoxMiIsIlNUQU5EQVJESVRFTUlEIjo2NDUxMjMuMH1dLCJ2aXNpdG9ySWQiOiI1QkFGNzg4NjNERDBENjQ3MUU4NkZENTYwQzU4NTFEMCJ9;+myserverGFSurvey=1;+ebNewBandWidth_.myserver.co.uk=251%3A1303383702897;+__utmb=151217894.1.10.1307618019;+__utmc=151217894 - myserver.co.uk 200 0 0 601 1506 0 W3SVC322653822_ex110609.log.log E:\w3\W3SVC322653822_ex110609.log.log crossdomain System.Text.RegularExpressions.Match[]
which is fine and dandy, but not dandy enough.
What I really want to do is get an export of the 7th column from the end where crossdomain occurs in the file. So this part in here:
**myserver.co.uk** 200 0 0 601 1506 0
(the myserver.co.uk)
any tips on this?
Cheers
Similar to Mjolinors' answer, but I'd try to keep the regexp as simple as possible. And since you've already selected lines with the word "crossdomain" you don't have to search for just that:
Get-Content test.csv | Foreach-Object
{
if ($_ -match '(\w+\.\w+\.\w+ \d+ \d+ \d+ \d+ \d+ \d+)')
{
$matches[1]
}
}
You won't get any 'Unexpected token' error, but you might have to tweak the regexp to get the result you want (I'm presuming you're looking for a three-dot domain and six numbers after it).
And always use '' for strings when you don't need variable extrapolation. it's much safer.
get-content test.csv |
foreach -object {
$_ -match ".+\s([a-z\.]+)\s[\s\d]+\S+\s\S+\s+crossdomain\s+\S+$" > $nul
$matches[1]
}