Is there a PowerShell equivalent to the dir /w of the old Windows command prompt? - powershell

In the older Windows command prompt dir /w formatted the directory output in wide format, providing a more at-a-glance view of contents to pick out folder names without having to scroll through the larger output that happens when they are all stacked vertically. This is especially useful when in VS Codes integrated terminal where the terminal window size is often restricted. Does PowerShell have an equivilent?

are you after this?
Get-ChildItem | Select-Object -Property Name
It should be an equivalent of "dir /w". If I remember correctly.

cmd /r dir /w as suggested by DSSO21 in the Comments above gives me the result I was expecting, albeit a more verbose command than I'd like.

Related

Generate log for last modified date of all files in a folder using CMD?

I have a folder of about 130 files, and I want to use a CMD prompt to generate a single .txt file with all their names and last modified dates. I've looked into DIR and .LastWriteTime but I can't figure it out. All I've searched about this topic leads to using Powershell or Batch or Linux but I don't have any of these resources, only CMD. I'm new to using CMD, but the worst part is that I got this done about a month ago and I cannot remember how I got this done! Incredibly frustrating.
Thank you so much!
EDIT: In the off chance it helps, last time I used such command (which I forgot about, and for the life of me I seem not to be able to find again), it generated this following file, maybe this may serve as a visual cue of what's the command I'm talking about. Once again thanks!
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/10/2018 3:55 PM 162256779 mobizen_20180210_155420.mp4
-a---- 2/10/2018 4:18 PM 111595959 mobizen_20180210_161816.mp4
-a---- 2/10/2018 4:20 PM 32643884 mobizen_20180210_162027.mp4
-a---- 7/15/2018 6:15 PM 60733357 mobizen_20180715_181514.mp4
-a---- 8/5/2018 5:08 PM 126381736 mobizen_20180805_170721.mp4
-a---- 8/30/2018 4:53 PM 81903211 mobizen_20180830_165306.mp4
As the question is specific to using cmd, and not a batch-file, or powershell…
All I've searched about this topic leads to using Powershell or Batch
or Linux but I don't have any of these resources, only CMD.
…you should not have included those tags.
Also as you've specifically stated that you…
want to use a CMD prompt to generate a single .txt file with all
their names and last modified dates.
…not the file attributes, file sizes, or table-like labelled headers; what follows is a modification of the example code in my opening comment. This time ensuring that all files are included, as per your question, (a standard for loop enumerates non hidden files), and including the redirection of the results to a .txt file too.
The below example has used relative paths for the target directory, (.\Music), and output file, (.\Desktop), so you may wish to change those to suit your actual situation. Also noting that the PowerShell output you've posted in your question body has outputted its results ordered alphabetically by filename, I have ensured that this does the same.
Dir ".\Music" /B /A:-D 1>NUL 2>&1 && (For /F "Delims= EOL= " %G In ('Dir ".\Music" /B /A:-D /O:N 2^>NUL') Do #For %H In (".\Music\%G") Do #Echo %~ntxH) 1> ".\Desktop\list.txt"
As a side note, if you wish to also have the attributes and filesizes, as in your PowerShell output, a simple change could achieve that too:
Dir ".\Music" /B /A:-D 1>NUL 2>&1 && (For /F "Delims= EOL= " %G In ('Dir ".\Music" /B /A:-D /O:N 2^>NUL') Do #For %H In (".\Music\%G") Do #Echo %~antxzH) 1> ".\Desktop\list.txt"
You can call powershell.exe, the PowerShell CLI from your batch file - such a call is costly in terms of performance, but gives you access to PowerShell's superior capabilities:
In the simplest case:
#echo off
:: Add / remove property names in the Select-Object call as needed.
:: If the dir. path has embedded spaces, enclose it in '...' or \"...\"
powershell.exe -noprofile -c ^
"Get-ChildItem C:\Users\cangrejo\Music\*.mp4 | Select-Object Mode, LastWriteTime, Length, Name" ^
> out.txt
Note: The above selection of output columns (properties) with Select-Object happens to be the default set of columns shown in Get-ChildItem's formatted output. If this default set will do, you can omit the Select-Object call; otherwise, modify the list of property names to suit your needs.
Note that the resulting file contains output that is formatted for the human observer, not for programmatic processing.
(And if you want more control over this for-display formatting, you can pipe your data to one of PowerShell's Format-* cmdlets, such as Format-Table.)
If you need later programmatic processing, use a structured text format such as CSV, via PowerShell's Export-Csv cmdlet:
#echo off
powershell.exe -noprofile -c ^
"Get-ChildItem C:\Users\cangrejo\Music\*.mp4 | Select-Object Mode, LastWriteTime, Length, Name | Export-Csv -NoTypeInformation out.csv"
Either way, you could easily add sorting by piping to
Sort-Object LastWriteTime -Descending before output, for instance.
Character-encoding note:
In the first command it is cmd.exe that saves to a file, using the encoding of the active code page, as reflected in the output from chcp; the default is the active OEM code page.
In the second command it is the default encoding of PowerShell's Export-Csv cmdlet that is used, which in Windows PowerShell defaults to ASCII(!) (in PowerShell (Core) 7+ it is now fortunately (BOM-less) UTF-8); use the -Encoding parameter to specify a different encoding; you can apply the same technique to the first command by appending | Out-File -Encoding ... to the PowerShell command instead of letting cmd.exe save the file.
For any directory your result will be returned by the default command, it just needs to be filtered by extension. Note this is not the best way for fast processing in a correct fashion see the better PowerShell solution already given by #mklement0
PowerShell Get-ItemProperty -Path *.mp4
then to save to file list you add > MP4.log
If the files are in another directory you use
PowerShell Get-ItemProperty -Path 'c:\some folder\with a space\*.mp4' > MP4.log
NOTE for PowerShell the 'single quotes' for a path with spaces.
Note:- if you dont need that first mode column you can do similar at the command line (For me CMD is faster than PowerShell) but you may need to edit for your local time output (Ignore my dummy data just a couple of old files I renamed) Note the list should default to time written but you could add /T:W if yours has any other over-ride.
Likewise #Compo has answered with a better more comprehensive cmd solution.
#echo Last Time written by me Length Name>mp4.log & echo ---- ---- ------- -- -- ------ ---->>mp4.log & dir /A:-D /O:D |find ".mp4" >> mp4.log & type mp4.log

Cannot find file path error for dir /b - Copying all file names script

I am trying to use a script that I've used before in Powershell, that is supposed to copy and paste all the file names inside a folder, into a text file.
I was able to use this script on a different computer last week, but can't do it now on my laptop.
Is there something I am not aware of?
The error it's giving is
Cannot find path 'C:\b' because it does not exist.
I tried removing the /b and I got a list of all the files but with other extra data like mode, last time write, length, name, and the extension of each file.
I really need the plain file name only. How can I do this? Thanks in advance!
the /b flag only works in cmd, not PowerShell
So you could try
cmd
dir /b
exit
Which will open CMD in your terminal and execute dir /b as a normal cmd command rather than PowerShell
Alternatively, just use PowerShell's Get-ChildItem (or gci for short)
To get just the plain file names using Get-ChildItem, you can do something like this:
# Assign the folder items to a variable $x
$x = gci
# Get only the names of those items
$x.name
See SS64 for details on CMD's dir and PowerShell's Get-ChildItem

How to call msys2 find command from PowerShell with correct shell escape characters?

I'm wondering how can I escape the following command from PowerShell so that it works?
PS C:\Users\buster\Documents\> find -name \*.c
PowerShell says: error not found *.c
PS C:\Users\buster\Documents\> find -name *.c
PowerShell says: error not found *.c
If you used find like that (without the full path) you most likely used the find.exe that ships with Windows (C:\Windows\system32\find.exe), which is more akin to grep than to Unix find. You get that behavior because Windows searches all directories in $env:PATH for files with the given name (and one of the extensions listed in $env:PATHEXT if no extension was specified), and executes the first match. Since %windir%\system32 is usually at the beginning of the PATH, executables from there take precedence.
You could add C:\msys64\msys64\usr\bin to the beginning of the PATH (before %windir%\system32), although I wouldn't recommend that. A better way would be to define an alias for the command:
New-Alias -Name 'find' -Value 'C:\msys64\msys64\usr\bin\find.exe'
Aliases take precedence over files. You could put the alias definition in your PowerShell profile so that it's automatically loaded whenever you start PowerShell.
Or you could simply use ls -r -fi '*.c' (short for Get-ChildItem -Recurse -Filter '*.c'), which would be the PowerShell way.
Ok false alarm..
Apparently its a case of windows having an executable with the same name as msys2's find.exe under c:\windows\system32 and the windows command getting higher priority in the path list. After explicitly typing out the full path to the msys64 version of find.exe it works.
PS C:\Users\buster\Documents\> C:\msys64\msys64\usr\bin\find -name \*.c
Also, Turns out there's a better way to find *.c files native to cmd.exe that you can call from powershell like this:
PS C:\Users\buster\Documents\> cmd /c dir /S /B *.v

How To Use A Windows Environment Variable Independent Of Shell?

I have a need within a .bat file to change to a certain directory which is referenced by an environment variable. Something along these lines:
cd %TMP%
And this works fine from Windows CMD shell. However if I try to run the bat within a Powershell terminal window, it appears that the command simply doesn't work. This does though:
cd $Env:TMP
So I'm trying to figure out how to keep things to one .bat file but still allow users to run it under both the CMD prompt and the PS prompt. I can think of some hacky ways to check to see if I'm under CMD (as opposed to PS) but I'd like to know if there's a better solution.
One thing I noticed is that the PROMPT environment variable is present with CMD but not with Powershell but, as I say, that seems a bit hacky and potentially error-prone.
I'm not trying to pad my rep so if this has already been asked and answered, please point me to it. I just want to find something less hacky than trying to figure out which shell the bat is being run in and changing the cd command to suit it.
By the way, since it may make a difference, I'm running under Powershell 4. I could probably use a .cmd file if that would make any difference but I'd be surprised if it did.
EDIT:
I guess maybe I wasn't as clear as I could be. I'm trying to figure out if there's a way to get the value of an environment variable that will work within a .bat file that will work regardless of whether or not the .bat file is run under the cmd shell or the powershell shell.
Running batch files from PowerShell works just fine. However, since the batch files run in a different interpreter (running .\your.bat is basically the same as running cmd /c .\your.bat), changing the working directory via cd %TMP% in the (CMD) child process doesn't change the working directory for the (PowerShell) parent process.
The syntax you use for variables in batch files is always %variable%.
Demonstration:
PS C:\> $PWD.Path
C:\
PS C:\> Get-Content .\test.bat
#echo off
echo before: %CD%
cd %TMP%
echo after: %CD%
PS C:\> .\test.bat
before: C:\
after: C:\Users\me\AppData\Local\Temp
PS C:\> $PWD.Path
C:\
The batch file echoes the path of the current working directory (%CD%) before and after changing the working directory to %TMP%. The working directory of the parent process (PowerShell) remains unchanged ($PWD.Path).

How to call findstr with /G parameter in powershell

I use findstr to recursively search several large directories for any lines that match any of the lines in searchList.txt.
findstr /SNIP /D:"C:\search Dir1;C:\search Dir2" /G:C:\searchList.txt *
I want to do the same thing in a Powershell script, either by calling the findstr command or doing something entirely in Powershell. Iterating over each item in searchList.txt and then looking in all the directories is too slow.
How do I call the above line in Powershell, or do the equivalent?
Thanks in advance.
You can call it in PowerShell by opening a PowerShell prompt, typing it in, and hitting [ENTER].
I don't see anything preventing you from running that command from PowerShell. findstr is not a native cmd command, it's a standalone .exe file bundled with Windows and located in the default system path (the System32 directory), so it's available from PowerShell.
You could do it in native PowerShell, but that would be an unnecessary headache. You'd have to do something like this
echo 'C:\search Dir1' 'C:\search Dir2' | Get-ChildItem | Select-String ((Get-Content C:\searchlist.txt) -join '|')
but excluding binary files would be a pain, because AFAIK there's no built-in way to check whether a file is text or binary. If you can rely on the extension, you could add -Filter *.txt after Get-ChildItem.
Bottom line: It's not worth it. Select-String is more versatile in terms of matching patterns, because you can use .NET regular expressions, but if the patterns you want to find are within findstr's limited regex capabilities, you're better off using findstr for this task, and your scripts will be portable because it's always included in Windows.