Select-String Fail

by Ricky Bobby at 2013-01-03 13:50:39

Hi all!

This one seems like it should be pretty easy, but I’m flummoxed.

I’m trying to search text files in a specific directory for a string. Easy right? However, I’ve tried it multiple ways and keep coming up empty handed.

Background is I’m trying to find a trial expiration note logged in text files on servers/desktops. It will go out on a grand scale, but first getting it to work on one machine would be best practice. Specifically, the text is "trial period has".

After much troubleshooting, I went back to the basics and just tried:

GCI "c:\prog files\xxx\xxx\xxx" -recursive -include *.txt (just using x instead of typing out full path here in this post)

That just takes me back to the prompt, no errors, no results. There’s definitely text files in that dir though. I can go deeper with the explanation, but I guess that’s step one. Why wouldn’t it be listing text files that exist?
by DonJ at 2013-01-03 13:55:01
That quite definitely works on my system, given a known path containing files with a *.txt filename extension.

All things being equal, that means something else is awry. What if you omit the -include parameter? What do you get back?
by Ricky Bobby at 2013-01-03 14:15:51
Right? Something definitely is funky. I get files listed otherwise just fine if that’s what you mean. And if this also helps narrow it down, running the following in the specific directory also returns files, just not the one I’m after:

Get-ChildItem | Where { $_ | Select-String "Trial" }
by Ricky Bobby at 2013-01-03 15:02:57
Maybe of some note, if I do a "dir .txt" in the directory in question, it returns all the text files no problem. Isn’t GCI just an alias for dir?
by rjc75 at 2013-01-03 22:02:23
Hi Ricky

Dir is an alias for Get-Childitem (get-alias dir)

I tried both of these commands and they both worked. As Don suggested, try omiting the -include.
get-childitem C:\ -recurse .txt | Where-Object {$_ | Select-String "Trial"}
get-childitem C:\ -recurse -include .txt | Where-Object {$_ | Select-String "Trial"}

Cheers
by nohandle at 2013-01-04 04:46:14
[quote="Ricky Bobby"]Maybe of some note, if I do a "dir .txt" in the directory in question, it returns all the text files no problem. Isn’t GCI just an alias for dir?[/quote]
In this case you use Filter instead of the Include parameter:
get-help Get-ChildItem -full| Out-String -Stream | Select-String "-Filter" -Context 0,10

-Filter <String>
....
Required? false
Position? 2

The path (#1 by position) is by default the current directory, so the filter is on the second place.
[quote="Ricky Bobby"]GCI "c:\prog files\xxx\xxx\xxx&quot; -recursive -include .txt [/quote]
here you call it with parameter ‘Recursive’ (and wrong path :)) instead of ‘Recurse’ isn’t this the cause?

This topic is by far the best descritpition of Include parameter is saw so far. http://stackoverflow.com/questions/7907 … tem-cmdlet
by Ricky Bobby at 2013-01-04 12:09:08
Ok, thanks for the replies. My machine was doing some other weird sh, so I finally got a chance to reboot on the off-chance this PoSH stuff was part of the weird sh. Here’s the latest:

Sorry, yeah, that was a typo here on the "recursive", heh. If I go to the directory in question and do:

get-childitem .txt

It pulls the file I’m after. Great. If I then append:

| Where-Object {$_ | Select-String "Trial"}

I get returned to the prompt with no result. However, I know that "trial" is in there as this is a test file to get the command correct.

If it helps, and so we don’t get caught up in this (though maybe we NEED to get caught up in this subset of the issue),the whole plan is to search hundreds of machines for a text file in a specific directory. In the words of the person I’m assisting . . . "My end goal is getting this to return the the last part of this line - 03-Jan-2013 08:00:00 service 300 trial period has 7 days left - I need that string out of the most recent entry".

Now, he sent me the issue initially with some regex appended, but was running into problems with it, namely that it also came back blank. So I decided to pull back and make sure we were targeting everything correctly. The fact that I can’t get "trial" to return to me with where-object makes me wonder . . .

All that make sense?
by nohandle at 2013-01-04 12:24:06
You are confusing get-childItem (or get-item) that gets the items info (filepath, name extension etc.) and the Get-content that gets the content of the file. then you can do select-string
similar to this:
Get-ChildItem -Path c:\temp -Filter tx
.txt | Get-Content | Select-String -Pattern "trial"
by Ricky Bobby at 2013-01-04 12:40:07
That’s what I thought too, however if I do the command as above (tried it before your post), same thing, returns to prompt with no result.

For what it’s worth, here’s the original one-liner with regex that he was trying to implement (I’ve redacted the directories):

[quote]‘gc ‘c:\program files(x86)\s…t\s…t\logs{2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt’ | select-object -last 30 | select-string -pattern "trial period has (?<days>\d{1,2})."’
What this is supposed to do is open that file (log file) and pull the last 30 lines and regex out that final string pattern. Everything works when I one off the commands, but when I run them together it tells me it cannot find the file.[/quote]

I noted to him that that file name is not consistent across machines so he’ll need to account for that and search the directory for all text files with that string and thus . . here we are. For testing purposes, I’m gc’ing that specific file which does have the "trial period" text in it, but that is what is coming back with no response/error.
by nohandle at 2013-01-05 02:24:50
[quote="Ricky Bobby"]That’s what I thought too, however if I do the command as above (tried it before your post), same thing, returns to prompt with no result.[/quote]
Do it step by step to find the error.
1] does the get-childItem part of the command list the file you need?
2] if you use get-item to retrieve the file object and pass it to the rest of the command does it return the data you want?
get-ITEM <full path to the file> | Get-Content | Select-String -Pattern "trial"
(note that here I use get-item not get-CHILDitem to get only the one file)
by RichardSiddaway at 2013-01-05 04:55:26
You don’t need to use get-item or get-content with select-string

All you need is

Select-String -Path C:\Test*.txt -Pattern "trial" -SimpleMatch

or

Get-ChildItem -Path C:\Test -Filter *.txt -Recurse | Select-String -Pattern "trial" -SimpleMatch
by Ricky Bobby at 2013-01-05 09:14:24
Well, at the end of the day, I’m able to find the file in the directory without issue. It’s only when I append select-string or otherwise ask it to go find me "trial" or "trial period has" which is about 6 lines down in the test text file that it returns me to a prompt with no result.
by nohandle at 2013-01-05 11:36:56
Can you answer the two questions I asked before please?
by Ricky Bobby at 2013-01-05 11:48:27
Sorry, didn’t realize you were waiting on a specific response (I’m sick, so a little slow on the uptake, heh). Below is a copy paste from PoSH console verbatim - only the directories were redacted. To answer though, 1st one, yes. 2nd one, no.

[quote]1/5/2013 12:09 PM C:\Users\xxx\xxx> get-childitem *.txt


Directory: C:\Users\xxx\xxx


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a— 1/3/2013 3:04 PM 1219878 {2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt


1/5/2013 2:42 PM C:\Users\xxx\xxx> get-item *.txt


Directory: C:\Users\xxx\xxx


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a— 1/3/2013 3:04 PM 1219878 {2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt


1/5/2013 2:42 PM C:\Users\xxx\xxx> get-item *.txt | gc | Select-String "trial"
1/5/2013 2:43 PM C:\Users\xxx\xxx>
[/quote]
by nohandle at 2013-01-05 11:50:22
get-item *.txt
Just this returns what?
by Ricky Bobby at 2013-01-05 11:54:43
the file (only txt file in that dir) in question. it’s noted in the second line above.
by Ricky Bobby at 2013-01-05 11:56:12
Sorry, not second line, but second command.
by nohandle at 2013-01-05 11:57:33
[quote="nohandle"]get-item *.txt
Just this returns what?[/quote]
Sorry I meant
get-item *.txt | gc
by Ricky Bobby at 2013-01-05 12:05:28
The full text of the file, as it should. Only thing I can think is that while it’s not strangely spaced in notepad, maybe that’s the issue? PoSH is doublespacing it so the pattern "trial" should be "t r i a l"?

See below (note that what I"m after is included here and at the top of the file):

[quote]1/5/2013 2:43 PM C:\Users\xxx\xxx> get-item *.txt | gc

1 1 - D e c - 2 0 1 2 1 2 : 4 7 : 5 2 s e r v i c e 3 0 0 t r i a l p e r i o d h a s 3 0 d a y s l
e f t[/quote]
by Ricky Bobby at 2013-01-05 12:06:51
For comparison purposes, this is how the file looks in notepad:

[quote]11-Dec-2012 12:47:52 service 300 trial period has 30 days left[/quote]
by megamorf at 2013-01-05 17:08:48
check the file encoding

See here: http://poshcode.org/2059
by nohandle at 2013-01-06 02:01:25
[quote="megamorf"]check the file encoding[/quote]
And specify the Encoding parameter for Get-Content or Select-String.
by Ricky Bobby at 2013-01-07 08:18:59
Sorry, in case you couldn’t tell I’m a bit of a weekend PoSHer, but trying to learn more when I can! Anyway, I’m a bit lost in regards to this piece of the pie.

I’ve put that script code in ISE and run it so the function is cached. Then navigated to the dir in question for testing and did:

[code2=powershell]PS C:\xxx\xxx\xxx> Get-FileEncoding C:\xxx\xxx\xxx{2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt

Get-FileEncoding : A positional parameter cannot be found that accepts argument '$null'.[/code2]

Which got the error above.
by megamorf at 2013-01-07 10:18:58
You should make sure to pass paths in quotes. In general double quotes should do, but if a path contains special characters you should use single quotes instead.

Try the following:
Get-FileEncoding 'C]
by Ricky Bobby at 2013-01-07 10:22:50
Same result - "cannot find path . . . . because it does not exist"
by megamorf at 2013-01-07 23:15:34
[quote="Ricky Bobby"]Same result - "cannot find path . . . . because it does not exist"[/quote]

Then the path you specified must be wrong. You can use the Cmdlet Test-Path to see if a file or folder exists.

I tested the function and it works just fine:
function Get-FileEncoding
{
[CmdletBinding()] Param (
[Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string]$Path
)

[byte]$byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path

if ( $byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf )
{ Write-Output 'UTF8' }
elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff)
{ Write-Output 'Unicode' }
elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff)
{ Write-Output 'UTF32' }
elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76)
{ Write-Output 'UTF7'}
else
{ Write-Output 'ASCII' }
}

mkdir C:\temp\long\file\path
new-item -ItemType file -Name '{2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt' -Path C:\temp\long\file\path -value "contentfortxtfile"

Get-fileencoding -path 'C:\temp\long\file\path{2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt'
ASCII
by Ricky Bobby at 2013-01-08 15:14:28
Yer right, I"m a doofus. So like your example above, the file is ASCII. Is that not a default? Actually need to specify the file encoding to search it for a string?
by Ricky Bobby at 2013-01-08 15:33:42
Ok, so even with encoding specified, still returns nothing but me, to the prompt. I first checked that it could find the txt file. It did, great. Then I piped that to select-string . . . below is a copy/paste from the console:

[code2=powershell]PS C:\Users\xxx\xxx> Get-ChildItem -Path C:\Users\xxx\xxx*.txt


Directory: C:\Users\xxx\xxx


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a— 1/3/2013 3:04 PM 1219878 {2FE24B03-E381-4E5D-9FF6-FC5D0BF622AA}.txt



PS C:\Users\xxx\xxx> Get-ChildItem -Path C:\Users\xxx\xxx*.txt | Select-String -Pattern "trial" -Encoding ascii

PS C]