Last active
September 10, 2022 17:26
-
-
Save tos-kamiya/2ebdc2b34ba89a38289705bb2c1b3f27 to your computer and use it in GitHub Desktop.
Expanding wildcards in shells of Windows using the dir or the ls commands
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# **DEPLICATED** the updated version is available at https://github.com/tos-kamiya/win_wildcard | |
# ref: https://stackoverflow.com/questions/55597797/detect-whether-current-shell-is-powershell-in-python | |
from typing import List, Optional | |
import locale | |
import os | |
import psutil | |
import re | |
import subprocess | |
SUBPROCESS_OUT_ENCODING = locale.getpreferredencoding() | |
def get_windows_shell() -> Optional[str]: | |
# Get the parent process name. | |
pprocName = psutil.Process(os.getppid()).name() | |
if re.fullmatch('pwsh|pwsh.exe|powershell.exe', pprocName): | |
return 'powershell' | |
if re.fullmatch('cmd.exe', pprocName): | |
return 'cmd' | |
return None | |
def expand_wildcard(filename: str) -> List[str]: | |
if not (filename.find('*') >= 0 or filename.find('?') >= 0): | |
return [filename] | |
s = get_windows_shell() | |
if s == 'powershell': | |
# Get-ChildItem -File -Name *.txt # option `-File` to match only files, no dirs. | |
out = subprocess.check_output(['powershell.exe', '-Command', 'Get-ChildItem', '-File', '-Name', filename]) | |
elif s == 'cmd': | |
# dir /A-D /B *.txt # option `/A-D` to match only files, no dirs. | |
out = subprocess.check_output(['dir', '/A-D', '/B', filename], shell=True) | |
else: | |
return [filename] | |
text = out.decode(SUBPROCESS_OUT_ENCODING) | |
r = [] | |
for L in text.split('\n'): | |
if L: | |
r.append(L) | |
return r | |
if __name__ == '__main__': | |
import sys | |
if get_windows_shell() is None: | |
sys.exit('script executed outside of Windows cmd.exe or powershell') | |
files = [] | |
for a in sys.argv[1:]: | |
r = expand_wildcard(a) | |
files.extend(r) | |
print('\n'.join(files)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The Windows shell leaves wildcard expansion to the command, so there is no standard way to expand wildcards.
At first, I thought the Win32API FindFirstFile and its Ex equivalents might be official, but these functions are designed to treat < and > as special characters, which is different from the shell's specification, so they were rejected.
Next, I thought it would be better to use the shell's dir or Get-ChildItem command to expand the file so that the user can check the expansion result, but it requires checking the current shell.
That's how I ended up with this. I've been surprised to figure out that such a basic function is hard to implement.