打印脚本所在的 Windows 目录的树,并根据 .gitignore 文件排除某些文件夹

Printing tree of windows directory where the script located and exclude some folders based on .gitignore file

提问人:Muhammad Ikhwan Perwira 提问时间:11/17/2023 最后编辑:Muhammad Ikhwan Perwira 更新时间:11/17/2023 访问量:27

问:

我有这个完全由 ChatGPT 生成的 powershell 脚本,因为我对 powershell 一无所知。相反,我更喜欢 Bash。

显示树.ps1

# Get the base path of the script
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
$basePath = (Get-Item $scriptPath).FullName

# Define the path to the .gitignore file
$gitIgnorePath = Join-Path $basePath ".gitignore"

# Check if the PSTree module is installed
if (-not (Get-Module -ListAvailable -Name PSTree)) {
  # Install the PSTree module if it's not installed
  Install-Module -Name PSTree -Scope CurrentUser -Force -AllowClobber
}

# Check if the .gitignore file exists
if (Test-Path $gitIgnorePath -PathType Leaf) {
  # Read the patterns from the .gitignore file and split into an array
  $excludePatterns = Get-Content $gitIgnorePath -ErrorAction SilentlyContinue | ForEach-Object { "$basePath\$_" }

  # Import the PSTree module
  Import-Module PSTree
  
  $tmpStdout = "tmp.txt"

  # Use the base path and exclude patterns in the Get-PSTree command
  Get-PSTree -Exclude $excludePatterns | Out-File $tmpStdout

  # Read the contents of the file
  $lines = Get-Content -Path $tmpStdout
  # Define the number of lines to skip from the beginning and end
  $headLength = 6   # Number of lines to skip from the beginning
  $tailLength = 2   # Number of lines to keep at the end
  # Filter the lines based on the specified criteria
  $lines[$headLength..($lines.Count - $tailLength - 1)] | Out-File $tmpStdout

  # Read the content of the input file
  $content = Get-Content $tmpStdout
  # Process each line, cutting the first 23 characters
  $content | ForEach-Object { $_.Substring(23) } | Out-File $tmpStdout
  Get-Content $tmpStdout
  Remove-Item $tmpStdout

}
else {
  Write-Host "No .gitignore file found."

  # Import the PSTree module without exclusion
  Import-Module PSTree
  Get-PSTree
}

它工作正常。它返回

cf-ztna-app
├── .gitignore
├── README.md
├── requirements.txt
├── show-tree.ps1
├── start-server.cmd
├── tmp.txt
└── src
    ├── main.py
    └── __init__.py

这是我的.gitignore:

.venv
.env

但正如你所看到的,我在高效的代码中使用临时文件来存储输出。我正在使用 .Out-File $tmpStdout

我为什么要这样做?因为我只想获取树输出,而不是来自命令外部模块(非内置)的任何开销或不必要的信息。Windows 中的内置命令未提供排除标志。PSTreetree

这是我不想期待的原始输出:



   Source: C:\Users\User\Documents\KULIAH\LAB_SOFTWARE\python_proj\cf-ztna-app

Mode            Length Hierarchy                                                               
----            ------ ---------                                                               
d-----         2.84 KB cf-ztna-app                                                             
-a----        10.00  B ├── .gitignore                                                          
-a----         1.11 KB ├── README.md                                                           
-a----        14.00  B ├── requirements.txt                                                    
-a----         1.70 KB ├── show-tree.ps1                                                       
-a----         0.00  B ├── start-server.cmd                                                    
-a----         0.00  B ├── tmp.txt                                                             
d-----       126.00  B └── src                                                                 
-a----       105.00  B     ├── main.py                                                         
-a----        21.00  B     └── __init__.py                                                     



许多空行和不必要的信息。Source

回复 @SantiagoSquarzon ,它没有排除 .gitignore 的内容:

(.venv) PS C:\Users\User\Documents\KULIAH\LAB_SOFTWARE\python_proj\cf-ztna-app> (Get-PSTree -Exclude *.gitignore*).Hierarchy
cf-ztna-app
├── .env
├── README.md
├── requirements.txt
├── show-tree.ps1
├── start-server.cmd
├── tmp.txt
├── src
│   ├── main.py
│   └── __init__.py
└── .venv
    ├── pyvenv.cfg
    ├── Scripts
    │   ├── activate
    │   ├── activate.bat
    │   ├── Activate.ps1
    │   ├── deactivate.bat
    │   ├── httpx.exe
    │   ├── pip.exe
    │   ├── pip3.11.exe
    │   ├── pip3.9.exe
    │   ├── pip3.exe
    │   ├── python.exe
    │   └── pythonw.exe
    ├── Lib
    │   └── site-packages
    └── Include
PowerShell 树视图 标准输出

评论

1赞 Santiago Squarzon 11/17/2023
看来你想要:)(Get-PSTree -Exclude *.gitignore*).Hierarchy
0赞 Muhammad Ikhwan Perwira 11/17/2023
@SantiagoSquarzon看到已编辑的问题,它没有排除.gitignore
0赞 Santiago Squarzon 11/17/2023
你这是什么意思?我没有看到你的更新中的任何子项.gitignore.gitignore
1赞 Santiago Squarzon 11/17/2023
我误读了你的评论,是你想要的吗?(Get-PSTree -Exclude $excludePatterns).Hierarchy
1赞 Muhammad Ikhwan Perwira 11/17/2023
@SantiagoSquarzon 谢谢,这就是我想要的。我只知道powershell中有属性/属性。这是我以前不知道的事情。bash脚本中似乎没有这样的属性/属性。

答:

1赞 Santiago Squarzon 11/17/2023 #1

基本上,您希望从输出中扩展属性,您可以使用以下命令简化代码:.HierarchyGet-PSTree

# Define the path to the .gitignore file
$gitIgnorePath = Join-Path $PSScriptRoot '.gitignore'

# Check if the PSTree module is installed
if (-not (Get-Module -ListAvailable -Name PSTree)) {
    # Install the PSTree module if it's not installed
    Install-Module -Name PSTree -Scope CurrentUser -Force -AllowClobber
}

# Check if the .gitignore file exists
if (Test-Path $gitIgnorePath -PathType Leaf) {
    # Read the patterns from the .gitignore file and split into an array
    $excludePatterns = Get-Content $gitIgnorePath -ErrorAction SilentlyContinue |
        ForEach-Object { Join-Path $PSScriptRoot $_ }

    # Use the base path and exclude patterns in the Get-PSTree command
    (Get-PSTree -Exclude $excludePatterns).Hierarchy
}
else {
    Write-Host 'No .gitignore file found.'
    Get-PSTree
}

请注意,$PSScriptRoot已包含根脚本路径。另请记住,默认情况下,cmdlet 将使用 -Depth 3,如果要显示完整的层次结构,则应使用 -Recurse

评论

0赞 Muhammad Ikhwan Perwira 11/17/2023
不幸的是,由于不支持的相对路径,该代码不适用于排除。我尝试了绝对路径。成功了。这就是为什么我告诉 ChatGPT 使用绝对路径的原因,其中基本路径是从脚本所在位置的当前目录中提取的。
0赞 Santiago Squarzon 11/17/2023
@MuhammadIkhwanPerwira嗯,我更新了我的答案,我认为这应该可以诚实地工作
1赞 Muhammad Ikhwan Perwira 11/17/2023
它只返回根项目目录 ''' (.venv) PS C:\Users\User\Documents\KULIAH\LAB_SOFTWARE\python_proj\cf-ztna-app> 。'C:\Users\User\Documents\KULIAH\LAB_SOFTWARE\python_proj\cf-ztna-app\foo.ps1' cf-ztna-app '''
0赞 Santiago Squarzon 11/17/2023
mm ok 将删除该更新。我之前在原始代码中有一个错别字,现在应该修复。 已包含根目录路径@MuhammadIkhwanPerwiraForEach-Object { Join-Path $PSScriptRoot $_ }$PSScriptRoot