I need to search for a term in a file and display an index in the search results so that referencing is easy.
The command in bash would be:
cat <file> | grep 'Table: ' | cat -n
What I have so far in Powershell:
Get-Content <file> | Select-String 'Table: ' | Select-Object -Property LineNumber, Line
Unfortunately, I didn't realize that LineNumber gives the actual line in the file and not the index in the results list.
How can I translate the bash command into its Powershell equivalent?
Indeed, the .Line property of the objects output by Select-Object indicates the line number of each match in a given input file.
PowerShell has no direct equivalent of cat -n (prepending a 1-based index to all input lines on output), but it's not hard to roll your own using the ForEach-Object cmdlet:
$i = 0
Get-Content file.txt | Select-String 'Table: ' | ForEach-Object {
"{0,6}`t{1}" -f ++$i, $_.Line
}
The above uses -f, the format operator, to left-space-pad to 6 characters (,6) the first RHS operand ({0}), which is the (incremented) index, ++$i, followed by a tab character (`t) and the second RHS operand ({1}), which is the input line at hand ($_.Line).
Just use WSL:
bash -c "cat <file> | grep 'Table: ' | cat -n"
This will run the bash code in powershell. For a true powershell option you could do this:
foreach ($line in $(Get-Content -Path <filepath> | Select-String 'Table: ')){
$count++
echo "$count $line"
}
Related
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
We have the following unix command:
/usr/bin/tail -n 1 %{path} | grep --silent -F "%{message}" && rm -f %{path}%
This:
/usr/bin/tail -n 1 %{path} gets the last line in the file that the path variable refers to
| grep --silent -F "%{message}" pipes the output to another command, grep, which checks if the output of the previous command is equal to the value of message
&& rm -f %{path}% if the values are equal, then delete the file refered to by path
The above line is in a configuration file which is allows for calls to be made to the underlying operating system.
I want to replicate the functionalirty on windows.
I tried this:
command => 'powershell -Command "& {Get-Item $args[0] | ? { (Get-Content $_ -Tail 1).Contains($args[1]) }| Remove-Item -Force}" "'%path%'" "'%message%'"'
This error is thrown:
Error: Expected one of #, {, } at line 15, column 131 (byte 498)
Line 15 is the line in the configuration file which contains the above.
Thanks
PowerShell solution:
$path = 'C:\path\to\your.txt'
$message = 'message'
Get-Item $path | ? { (Get-Content $_ -Tail 1).Contains($message) } | Remove-Item -Force
If you want to run it from a command line, call it like this:
powershell -Command "& {Get-Item $args[0] | ? { (Get-Content $_ -Tail 1).Contains($args[1]) } | Remove-Item -Force}" "'C:\path\to\your.txt'" "'message'"
You can use tailhead.bat (pure batch script utility) that can be used to show lasts/fists lines of a file.Instead of Grep you can use findstr or find :
tailhead.bat tailhead -file=%pathToFile% -begin=-3|find "%message%"
I'm looking for the PowerShell equivalent to grep --file=filename. If you don't know grep, filename is a text file where each line has a regular expression pattern you want to match.
Maybe I'm missing something obvious, but Select-String doesn't seem to have this option.
The -Pattern parameter in Select-String supports an array of patterns. So the one you're looking for is:
Get-Content .\doc.txt | Select-String -Pattern (Get-Content .\regex.txt)
This searches through the textfile doc.txt by using every regex(one per line) in regex.txt
PS) new-alias grep findstr
PS) C:\WINDOWS> ls | grep -I -N exe
105:-a--- 2006-11-02 13:34 49680 twunk_16.exe
106:-a--- 2006-11-02 13:34 31232 twunk_32.exe
109:-a--- 2006-09-18 23:43 256192 winhelp.exe
110:-a--- 2006-11-02 10:45 9216 winhlp32.exe
PS) grep /?
I'm not familiar with grep but with Select-String you can do:
Get-ChildItem filename.txt | Select-String -Pattern <regexPattern>
You can also do that with Get-Content:
(Get-Content filename.txt) -match 'pattern'
I had the same issue trying to find text in files with powershell. I used the following - to stay as close to the Linux environment as possible.
Hopefully this helps somebody:
PowerShell:
PS) new-alias grep findstr
PS) ls -r *.txt | cat | grep "some random string"
Explanation:
ls - lists all files
-r - recursively (in all files and folders and subfolders)
*.txt - only .txt files
| - pipe the (ls) results to next command (cat)
cat - show contents of files comming from (ls)
| - pipe the (cat) results to next command (grep)
grep - search contents from (cat) for "some random string" (alias to findstr)
Yes, this works as well:
PS) ls -r *.txt | cat | findstr "some random string"
So I found a pretty good answer at this link:
https://www.thomasmaurer.ch/2011/03/powershell-search-for-string-or-grep-for-powershell/
But essentially it is:
Select-String -Path "C:\file\Path\*.txt" -Pattern "^Enter REGEX Here$"
This gives a directory file search (*or you can just specify a file) and a file-content search all in one line of PowerShell, very similar to grep. The output will be similar to:
doc.txt:31: Enter REGEX Here
HelloWorld.txt:13: Enter REGEX Here
I find out a possible method by "filter" and "alias" of PowerShell, when you want use grep in pipeline output(grep file should be similar):
first define a filter:
filter Filter-Object ([string]$pattern) {
Out-String -InputObject $_ -Stream | Select-String -Pattern "$pattern"
}
then define the alias:
New-Alias -Name grep -Value Filter-Object
final, put the former filter and alias in your profile:
$Home[My ]Documents\PowerShell\Microsoft.PowerShell_profile.ps1
Restart your PS, so you can use it:
alias | grep 'grep'
References
alias:
Set-Alias here
New-Alias here
Filter (Special function) here
Profiles (just like .bashrc for bash): here
out-string (this is the key) here:
in PowerShell Output is object-based hereļ¼so the key
is to convert object to string and grep the string.
Select-String here:
Finds text in strings and files
This question already has an answer, but I just want to add that in Windows there is Windows Subsystem for Linux WSL.
So for example if you want to check if you have service named Elasicsearch that is in status running you can do something like the snippet below in powershell
net start | grep Elasticsearch
but select-String doesn't seem to have this option.
Correct. PowerShell is not a clone of *nix shells' toolset.
However it is not hard to build something like it yourself:
$regexes = Get-Content RegexFile.txt |
Foreach-Object { new-object System.Text.RegularExpressions.Regex $_ }
$fileList | Get-Content | Where-Object {
foreach ($r in $regexes) {
if ($r.IsMatch($_)) {
$true
break
}
}
$false
}
Maybe?
[regex]$regex = (get-content <regex file> |
foreach {
'(?:{0})' -f $_
}) -join '|'
Get-Content <filespec> -ReadCount 10000 |
foreach {
if ($_ -match $regex)
{
$true
break
}
}
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"
I have a binary executable that takes a list of file paths as arguments, e.g.,
C:\Tool.exe C:\Files\File1.txt C:\Files\File2.txt
I would like to call this tool from Powershell. The question is, how can I get the output of get-childitem all on one line?
If I run:
ls C:\Files\*.txt | select FullName
I get one path per line. How can I concatenate the results?
In PowerShell 2.0 you can use the -join operator:
(ls C:\Files\*.txt | %{ $_.FullName }) -join ' '
In PowerShell 1.0 you can set $OFS, which is used to combine a sequence of items when they are used as a string:
$ofs = ' '
"$(ls C:\Files\*.txt | %{ $_.FullName })"