To find files in a directory that have both "foo" and "bar" in the filename, we can use:
Get-ChildItem | Where-Object {$_.Name -like "*foo*" -and $_.Name -like "*bar*"}
Is there a more elegant way to write (or query for) this?
4 Answers
Why do you consider your command inelegant? If you're just after more terse code, this might be better on Code Review.
Incidentally, I don't think that command would work.
If you want to use -like, then add wildcards:
gci | ? {$_.Name -like "*foo*" -and $_.Name -like "*bar*"}If you don't want to use wildcards, use -match:
gci | ? {$_.Name -match "foo" -and $_.Name -match "bar"}There are many ways to skin a cat
gci *foo* | ? {$_.Name -in (gci *bar*).Name}I think more elegant code is subjective and really depends on your coding style. I personally prefer your line of code as it's not cryptic at all, and it's fairly compact for what it does.
2How I understand the title of this question the answer would be like one of:
'*.txt','*.log' | ForEach-Object { Get-ChildItem $_ } # 'pure' Powershell
where.exe /r . *.txt *.log # external commandBut for just getting files that have 'foo' and 'bar' in their names (which I consider one pattern) some obvious solutions could be:
Get-ChildItem *foo*bar* # if the order is given
Get-ChildItem ` | Where-Object Name -match 'foo.*bar|bar.*foo' # if not Another way to do this is to use regular expressions match:
Get-ChildItem | Where-Object {$_.Name -match "(?=.*foo)(?=.*bar)"
If you are after shorter version(s), you could also abbreviate it to:
gci |? {$_.Name -match "(?=.*foo)(?=.*bar)"
Here are two possibilities:
gci | ? Name -like *foo* | ? Name -like *bar*
gci *foo* | ? Name -like *bar*I agree with ST8 though that your version is fine.