Reputation: 91
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 $_
.
Upvotes: 0
Views: 100
Reputation: 27756
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" }
Upvotes: 2
Reputation: 18940
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.
Upvotes: 1
Reputation: 7057
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!
Upvotes: 1