ls(get-childItem)递归遍历符号链接symlink
-FollowSymlink <System.Management.Automation.SwitchParameter>
By default, the `Get-ChildItem ` cmdlet displays symbolic links to directories found during recursion, but doesn't recurse into them. Use the FollowSymlink parameter to search the
directories that target those symbolic links. The FollowSymlink is a dynamic parameter and is supported only in the FileSystem provider.
## powershell version
默认情况下,ls -R
不会遍历到符号链接/junction link所指的目录 明白这一点在某些情况下很重要(特别是下文中的模拟tree的函数)
该版本也是默认不会遍历进入符号链接,不过,您可以指定-FollowSymlink
来迫使遍历能够访问符号链接所指向的目录
powershell version(no tree branch)
function tree_pwsh
{
param (
$traverseType = '' ,
$path = './' ,
$maxDepth = '2' ,
$exclude = ''
)
$depth = 1
$times = 0
function listRecurse
{
param (
$traverseType = '' ,
$path = ''
)
if ($traverseType -eq 'd' )
{
$lst = (Get-ChildItem -Directory $path )
}
else
{
$lst = (Get-ChildItem $path )
}
$len = $lst .Length
$times ++;
$lst | ForEach-Object {
$len -- ;
if ($_ .BaseName -like $exclude )
{
}
else
{
$indent_tree = "│`t" * ($depth - 1 ) + '│'
$pathNameRelative = $_ .baseName
Write-Output "$indent_tree `──($depth )$ ($pathNameRelative )"
if ((Get-Item $_ ) -is [system.io.directoryinfo ] )
{
if (@ (Get-ChildItem $_ ).Count -gt 0 )
{
$branch = $indent_tree + ' ├────'
if ($depth -eq $maxDepth )
{
$branch += '......'
}
$branch
}
$depth ++
if ($depth -le $maxDepth -or $maxDepth -eq 0 )
{
listRecurse -path $_ .FullName -traverseType $traverseType
}
$depth --
}
}
}
}
listRecurse -traverseType $traverseType -path $path
}
示例效果
PS D:\repos\blogs\neep> recurseTree -maxDepth 3
1 D:\repos\blogs\neep\408
2 D:\repos\blogs\neep\408 \ComputerNetwork
3 D:\repos\blogs\neep\408 \ComputerNetwork\concepts.md
3 D:\repos\blogs\neep\408 \ComputerNetwork\ipv6.md
2 D:\repos\blogs\neep\408 \os
3 D:\repos\blogs\neep\408 \os\exercise5.md
2 D:\repos\blogs\neep\408 \principlesOfCompilers
3 D:\repos\blogs\neep\408 \principlesOfCompilers\image
3 D:\repos\blogs\neep\408 \principlesOfCompilers\subSet.md
2 D:\repos\blogs\neep\408 \principlesOfComputer
3 D:\repos\blogs\neep\408 \principlesOfComputer\机器数问题
3 D:\repos\blogs\neep\408 \principlesOfComputer\image
3 D:\repos\blogs\neep\408 \principlesOfComputer\1646647596000 .png
3 D:\repos\blogs\neep\408 \principlesOfComputer\补码和模的故事.md
3 D:\repos\blogs\neep\408 \principlesOfComputer\存储单元地址.md
powershell tree_pwsh(with tree branch)
function tree_pwsh
{
param (
$traverseType = '' ,
$path = './' ,
$maxDepth = '2' ,
$exclude = ''
)
$depth = 1
$times = 0
function listRecurse
{
param (
$traverseType = '' ,
$path = ''
)
if ($traverseType -eq 'd' )
{
$lst = (Get-ChildItem -Directory $path )
}
else
{
$lst = (Get-ChildItem $path )
}
$len = $lst .Length
$times ++;
$lst | ForEach-Object {
$len -- ;
if ($_ .BaseName -like $exclude )
{
}
else
{
$indent_tree = "|`t" * ($depth - 1 )
Write-Output "$indent_tree `\_($depth )$ ($_ .FullName)"
if ((Get-Item $_ ) -is [system.io.directoryinfo ] )
{
if (@ (Get-ChildItem $_ ).Count -gt 0 )
{
$branch = $indent_tree + ' \____.'
if ($depth -eq $maxDepth )
{
$branch += '......'
}
$branch
}
$depth ++
if ($depth -le $maxDepth -or $maxDepth -eq 0 )
{
listRecurse -path $_ .FullName -traverseType $traverseType
}
$depth --
}
}
}
}
listRecurse -traverseType $traverseType -path $path
}
效果
updating version
将每层的文件和目录分类(优先答应文件,然后在处理文件夹,使得结果更加紧凑)
"""
设定一个递归函数travers_dir(dirName,depthStop,...);
该函数支持指定递归的深度;
同时要求能够体现目录间的层次(通过制表符缩进来表达 🅱 )
具体规则如下:当指定深度depth_stop<=0时,尽可能的递归当前目录下的子目录(否则递归的深度就是depth_stop,或者不超过depth_stop);
默认尽可能递归.
该函数接收一个目录字符串参数,函数进入改目录打印出所有文件名以及目录名此外,如果被打印的对象时目录时,需要以该目录为参数在调用一次traverse_dir
在以下实现中,您不应当传入第三个参数,如果为了安全起见,您可以为其在做一次浅封装,使得函数只有两个参数,而函数内部则调用traverse_dir()
"""
from sys import argv
import os
import os.path as op
def empyt (obj ):
...
d = print
d = empyt
pathOut = "fileOutByTreePyScript"
""" 本函数主要用到:os.listdir()以及os.path.isdir()以及一些判断技巧和debug过程中的控制技巧,去掉日志语句后,代码量较少 """
def separate_line (num=50 ,separator='>' ):
print (f'😎🎶:{num*separator} ' )
def traverse_dir (dirName="." , stop_depth=0 , depth=0 ):
if depth == 0 :
separate_line(separator='~' )
print (
f'😁executing the traverse_dir with the paramters: \n@dirName={dirName} ,\n@stop_depth={stop_depth} ,\n@depth={depth} ' )
separate_line(separator='^' )
if stop_depth > 0 :
if stop_depth > depth:
pass
else :
return
d("\t new invoke of traverse_dir()" )
items = os.listdir(dirName)
items.sort(key=lambda item: op.isdir(op.join(dirName, item)))
d(items)
if (items):
for item in items:
newPath = op.join(dirName, item)
d(newPath)
isdir = op.isdir(newPath)
if isdir:
if item == ".git" :
continue
d("dirName:" +item+"\twill be enter by new invoke of traverse_dir" )
fileLogo = "☪ "
folder_Logo = "📁"
dir_logo="->"
depthStr = folder_Logo+"depth:" +str (depth+1 )+dir_logo
indent = depth*"\t"
dirStr = newPath
dirStr = indent+depthStr+ dirStr
print (dirStr)
traverse_dir(newPath, stop_depth, depth+1 )
else :
fileStr = depth*"\t" +0 *" " +"⭐:" +item
print (fileStr)
def append (content, fileName=pathOut ):
with open (fileName, 'a' ) as fout:
fout.write(content+"\n" )
def generate_defaultParams ():
dirPrefix = "d:/repos/scripts/"
dirPost = ""
return dirPrefix+dirPost
if op.exists(pathOut):
os.remove(pathOut)
if __name__ == "__main__" :
os.chdir(os.getcwd())
separate_line(separator="-" )
print ("😊info:there is in the tree_pyScript.py;\n try to offer the tree server...💕" )
dirName = "."
dirName = generate_defaultParams()
depth = 2
if len (argv) > 1 :
dirName = argv[1 ]
if len (argv) > 2 :
depth = argv[2 ]
if (argv[2 ].isdigit()):
depth = int (depth)
if (argv[1 ].startswith("depth=" )):
depth = int (argv[1 ][6 :])
print (argv[1 ][6 :])
else :
...
if (argv[2 ].startswith("dirName=" )):
dirName = argv[2 ][len ("dirName=" ):]
if (argv[1 ] in ["-?" , "?" , "/?" , "\\?" ]):
print ("function usage:traverse_dir([dirName],[depth]💕" )
else :
print ("you do not offer any parameter,now try execute the default behaviour💕" )
traverse_dir(dirName, depth)
tip='😘work dir tips for user:'
separate_line()
print (tip,"\n" ,os.getcwd(),f'😘' )
preview
old version
"""
"""
设定一个递归函数travers_dir(dirName,depthStop,...);
该函数支持指定递归的深度;
同时要求能够体现目录间的层次(通过制表符缩进来表达 🅱 )
具体规则如下:当指定深度depth_stop<=0 时,尽可能的递归当前目录下的子目录(否则递归的深度就是depth_stop,或者不超过depth_stop);
默认尽可能递归.
该函数接收一个目录字符串参数,函数进入改目录打印出所有文件名以及目录名此外,如果被打印的对象时目录时,需要以该目录为参数在调用一次traverse_dir
在以下实现中,您不应当传入第三个参数,如果为了安全起见,您可以为其在做一次浅封装,使得函数只有两个参数,而函数内部则调用traverse_dir()
"""
from sys import argv
import os
import os.path as op
# 定义一个空函数,来控制日志打印与否(免注释)
def empyt(obj):
...
d = print
# 控制是否打印调试日志
d = empyt
""" 本函数主要用到:os.listdir()以及os.path.isdir()以及一些判断技巧和debug过程中的控制技巧,去掉日志语句后,代码量较少 """
def traverse_dir(dirName=".", stop_depth=0, depth=0):
# depth=0
if stop_depth > 0:
if stop_depth > depth:
pass
else:
return
d("\t new invoke of traverse_dir()")
items = os.listdir(dirName)
d(items)
if (items):
for item in items:
# newPath = dirName+"/"+item
# newPath的存在性可以保证,但是是否为目录需做进一步判断
newPath = op.join(dirName, item)
d(newPath)
# notice the paramter of isdir()
if op.isdir(newPath):
if item == ".git":
continue
d("dirName:"+item+"\twill be enter by new invoke of traverse_dir")
leftEmoji = "-------😇-------"
rightEmoji = "-------🙂-------"
depthStr = "detpth:"+str(depth+1)
indent = depth*"\t"
dirStr = newPath
fileLogo = "☪ "
folderLogo = "📁 "
dirStr = indent+depthStr+folderLogo + dirStr
print(dirStr)
# out(dirStr)
traverse_dir(newPath, stop_depth, depth+1)
else:
fileStr = depth*"\t"+"⭐:"+item
print(fileStr)
# out(fileStr)
""" """
pathOut = "file_dir_out"
def append(content, fileName=pathOut):
with open(fileName, 'a') as fout:
# 注意换行
fout.write(content+"\n")
# dirName = "d:/repos/learnPython/ppt_source_code"
# dirName = "./../algorithm/"
dirPrefix = "d:/repos/PythonLearn/"
dirPost = "algorithm"
dirPost = ""
# dirName = op.join(dirPrefix, dirPost)
dirName = dirPrefix+dirPost
# 当反复调试的时候可以预处理将之前的文件删除
# 如果有必要,可以采用将原来的文件重名名的方式(以输出时间为名字后缀是一种选择)
if op.exists(pathOut):
# 或者用rename()
os.remove(pathOut)
# 将中途的输出结果(比如日志)输出到文件中(采用append模式)
out = append
depth = 0
if __name__ == "__main__":
# test
# os.chdir("D:/repos/")
# traverse_dir(".",2)
if len(argv) > 1:
dirName = argv[1]
if len(argv) > 2:
# print(f"get the argv from commandLine:{argv[1]}😊{argv[2]}")
depth = argv[2]
if(argv[2].isdigit()):
depth = int(depth)
if(argv[1].startswith("depth=")):
depth = int(argv[1][6:])
print(argv[1][6:])
if(argv[2].startswith("dirName=")):
dirName = argv[2][len("dirName="):]
if(argv[1] in ["-?", "?", "/?", "\\?"]):
print("traverse_dir(dirName,depth)")
# else:
traverse_dir(dirName, depth)
效果
使用方式
python <脚本名> 目录名 深度(0则为无限深度)
例如: python tr_py d:\repos\web 2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了