Skip to content

Instantly share code, notes, and snippets.

@tos-kamiya
Last active September 10, 2022 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tos-kamiya/2ebdc2b34ba89a38289705bb2c1b3f27 to your computer and use it in GitHub Desktop.
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
# **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))
@tos-kamiya
Copy link
Author

tos-kamiya commented Sep 10, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment