How to execute find command with Powershell - windows

I'm learning Git Internals https://git-scm.com/book/en/v1/Git-Internals-Git-Objects
When I try to execute this command on Windows (using cmder a better console http://cmder.net/)
find .git/objects
I get an error
What should I do instead ?

find.exe in Windows is not the equivalent of find in linux.
The equivalent of find [startpath] in PowerShell would be:
Get-ChildItem [startpath] -Name
and in cmd.exe, it would be:
dir /B [startpath]

For an equivalent of:
find foo -type f
... I use:
Get-Children foo -Name -Recurse -File | % { $_ -replace "\\", "/" }

Use the FullName attribute, otherwise it will not show the full name if the path is long:
(Get-ChildItem -Path 'C:\dist\work' -Force -Recurse -ErrorAction 'SilentlyContinue' -Filter "objects").FullName
C:\dist\work\bam-client\.git\objects
C:\dist\work\bam-extras\.git\objects
:

Related

How to combine TYPE and DIR command in windows cmd?

I have to translate a LINUX command into a Windows one. This is the command:
cat $(find folderName)/fileName
Searching online I found that:
cat can be translated with type
find can be translated with dir
So I tried to use something like this:
type #(dir folderName /s)/fileName
type < (dir folderName /s)/fileName
They are wrong, but I can't find any solution to combine them.
Can someone help me?
I am confident that others will provide FOR loop solutions.
This is not difficult if you use PowerShell Core or Windows PowerShell. If you are on a supported Windows system, Windows PowerShell was installed with it and is available.
While you might rightly say that this is more typing than needed in a bash/ksh script, it will run equally well on Linux, MacOS, and Windows without any modification. No 'translate' needed.
Get-Content -Path $(Get-ChildItem -Recurse -File -Path '.' -Filter 'sheet1.xml' |
Where-Object { $(Split-Path -Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
The amount of typing can be reduced by using aliases. While that is ok at an interactive shell, it is bad practice to encode aliases into script files.
gc $(gci -rec -file 'sheet1.xml'|?{$(Split-Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
If you are desperate to run this from a cmd command prompt, the following could be used.
powershell -NoLogo -NoProfile -Command ^
Get-Content -Path $(Get-ChildItem -Recurse -File -Path '.' -Filter 'sheet1.xml' ^| ^
Where-Object { $(Split-Path -Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
powershell -NoLogo -NoProfile -Command ^
gc $(gci -rec -file 'sheet1.xml'^|?{$(Split-Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName

Piping in PowerShell: Connot bind argument to parameter <parameter> because it is null

I have been practicing PowerShell by dealing with some of the tasks I could do in the file explorer. I am organizing some files for a python project which I am doing. My goal was to copy all python files in the current directory into the "V0.0_noProgressBar" directory:
ls -Filter "*.py" | copy $_ "V0.0_noProgressBar"
but it fails:
Cannot bind argument to parameter 'Path' because it is null.
At line:1 char:26
+ ls -filter "*.py" | copy $_ "V0.0_noProgressBar"
+ ~~
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,
Microsoft.PowerShell.Commands.CopyItemCommand
I assume this should be sufficient information to figure this out, let me know if more is needed. I have run into similar issues a number of times, so there must be a fundamental problem with my understanding of the placeholder $_.
This can be simplified to:
Copy-Item *.py V0.0_noProgressBar
To answer original question, why $_ is not working:
$_ is only valid in script contexts, not just anywhere in the pipeline. E. g. you could use it in a script block of ForEach-Object:
Get-ChildItem -filter "*.py" | ForEach-Object { Copy-Item $_ "V0.0_noProgressBar" }
To augment zett42's succinct answer. $_ makes an appearance in several areas of PowerShell. Some cmdlets allow it's use in a script block the output of which is treated as the argument to the parameter. In keeping with the question the *-Item cmdlets can make use of $_.
Get-ChildItem -Filter "*.txt" | Copy-Item -Destination { "C:\"+ $_.Name }
Obviously that's just an example. Perhaps a more useful case is Rename-Item -NewName { ... $_ ... }. -NewName which also works this way.
Other common cmdlets that make use of $_ are Select-Object, Sort-Object, & Group-Object. Overlapping some of these $_ is used by many cmdlets to help define calculated properties. I strongly recommend reading this about topic. Along with the use of $_ calculated properties are extremely useful. I use them with Select-Object everyday!
If you really want to pass a collection of files through a pipeline,
you can do this:
ls -Filter *.py | Copy-Item -Destination "V0.0-NoProgressBar"
Here the Copy-Item cmdlet has no -Path parameter, so it gets the files from the pipeline. See Help Copy-Item -full to see that the -Path parameter can accept pipeline input.
This is not as simple as answers already given, but it does show an alternative to trying to use $_ in a context where it is unavailable.

How to move set of files having multiple extension to another directory using PowerShell?

I need to move set of specific files having different extension to another folder.
I have following filtered files in the directory.
file1.txt
file2.xml
file3.dll
I have kept the above files in the variable $files and I need to move each of files to another folder.
Below is the code I tried.
foreach ($fileType in $files) {
Get-ChildItem -Path C:\Files -Filter "$fileType*." -Recurse |
Move-Item -Destination C:\Dest
}
I am getting following error
Get-ChildItem : Illegal characters in path.
At line:1 char:38
+ ... lude_files){Get-ChildItem -Path C:\Files
Appreciate if anyone can help on this?
An easy way to do this
ls C:\files | Foreach {
Move-Item -Path C:\files\$filetype -Destination C:\dest
}
If all the files you are after share a common 'starts-with' name like file as in your example, the below should do what you want. It uses the -Include parameter where you can add an array of (in this case) extensions to look for.
Get-ChildItem -Path 'C:\Files' -Filter 'file*' -Include '*.txt','*.xml','*.dll' -Recurse |
Move-Item -Destination 'C:\Dest'
Note: the -Include parameter only works when also used together with the -Recurse switch, OR by appending \* after the path (like in C:\Files\*)

Windows Equivalent to Linux: Find -name

I am trying to figure out a command in the CLI which I know in Linux Ubuntu but I need to apply it in Microsoft.
Moreover, I am trying to find all files within a folder with a specific name. Particularly, I try to find all files which contain the term 'test' in their name.
Here is the command which I know in Linux:
find \home\user\data -name '*test*'
Does anyone know the equivalent in the windows command line?
You will looking for Get-ChildItem
Get-ChildItem C:\Test -Filter "*test*"
In PowerShell you can use Get-ChildItem to find files and folders.
If you want to use regular expressions, you can combine Get-ChildItem with the Select-String or Where-Object cmdlets.
Get-ChildItem -Path C:\ -Recurse | Select-String -pattern "Regex"
Get-ChildItem -Path C:\ -Recurse | Where-Object -FilterScript {$_.name -match "regex"}
You're looking for the "dir" command. To accomplish the same thing as your original search, you would use
dir \home\user\data "*test*"

Converting find and copy in bash to some in Windows PowerShell

I am trying to convert code from bash to PowerShell like this:
In bash:
find ./searchfolder -type f -name "something" | xargs cp -t ./destinationfolder
I mean "find" command finds
./searchfolder/something
./searchfolder/0.15/something
./searchfolder/0.25/something
and "copy" command copies the files in the new directory (with preserving folder structure)
./destinationfolder/something
./destinationfolder/0.15/something
./destinationfolder/0.25/something
How can i do that? Thanks in advance.
How about using the Filter parameter on the Copy-Item command? This might get you close.
cp ".\searchfolder" -Recurse -Filter "something" -Destination ".\destinationfolder"
cp is an Alias of Copy-Item BTW.
This is assuming you are looking for text files in C:\temp and moving them to C:
Get-Childitem –Path C:\Temp -Recurse -Include *.txt* | ForEach-Object { mv $_.fullName c:\ }
Regards!
I am assuming this will be the folder structure. Only one Subdirectory inside Sourcefolder.
SourceFolder
--f1
-test.txt
--f2
-test.txt
--f3
-other.txt
and copy folders which has file named test
Destination
--f1
-test.txt
--f2
-test.txt
Script
cd D:\Vincent\PSTesting
$Path = 'Searchfolder'
Get-ChildItem $Path -Recurse -Filter *Test* -File | foreach {
$SourceFolder = $_.Directory -replace "^.*$Path"
Copy-Item -Path $Path\$SourceFolder -Destination "D:\Vincent\PSTesting\Destinationfolder\" -Verbose -Recurse
}

Resources