快速生成树形结构的纯文本

今天帮朋友整理一些材料,需要为这些材料整理一个目录。之前有研究过一些方案,例如:

这些方案有一个共性:麻烦。也就是无法像手头的工具一样拿来就用。于是发掘了一番,发现 tree 这个 dos 时代的命令刚好能满足需要。该命令的帮助如下:

以图形显示驱动器或路径的文件夹结构。

TREE [drive:][path] [/F] [/A]

   /F   显示每个文件夹中文件的名称。
   /A   使用 ASCII 字符,而不使用扩展字符。

我们可以用以下命令将 D:\work 下的结构输出到 output.txt 文本文件:

TREE "D:\work" /F /A > output.txt

然后用记事本之类的文本编辑器对它进行简单的编辑,就可以达到目的。

还可以拓展一下思路:在撰写文章的时候,常常需要描述一个有层次的结构(可以是心得体会之类的,不仅限于描述一系列文件)。此时可以在硬盘里创建一个临时目录,在里面创建一些文件夹和文件,用资源管理器拖拽调整目录结构,然后用上述命令导出一个目录文件,就可以快速地用于文档的撰写了。请不要徒手编辑这样的文本,因为那样很愚蠢,调整起来也相当费功夫。

命令执行效果参考:

卷 os 的文件夹 PATH 列表
卷序列号为 0000002C 000E:BD6F
C:.
|   HaxLogs.log
|   setmockup.log
|   WEVTUTIL.exe
|
+---adt-bundle-windows-x86
|   |   SDK Manager.exe
|   |
|   +---android-ndk-r9
|   |   |   documentation.html
|   |   |   GNUmakefile
...
|   |   |   README.TXT
|   |   |   RELEASE.TXT
|   |   |
|   |   +---build
|   |   |   +---awk
|   |   |   |       check-awk.awk
|   |   |   |       extract-debuggable.awk

快速运行 .ps1 脚本的 N 种方法

由于安全的原因,微软禁止以双击的方式执行 PowerShell 的 .ps1 脚本。但如果我们一味地追求效率,而暂时“无视”其安全性的话,要怎样快速地执行 .ps1 脚本呢?以下是 QQ 群里讨论的一些方案:

为每个 .ps1 配一个 .cmd 批处理文件

这种方法适用于可能需要将 PowerShell 脚本发送给朋友执行,而朋友可能只是初学者或普通用户的场景,并且该脚本不会修改注册表。具体做法是:将以下代码保存为一个 .cmd 文件,放在 .ps1 的同一个目录下。注意主文件名必须和 .ps1 的主文件名一致

@set Path=%Path%;%SystemRoot%\system32\WindowsPowerShell\v1.0\ & powershell -ExecutionPolicy Unrestricted -NoExit -NoProfile %~dpn0.ps1

例如,您希望朋友执行 My-Script.ps1,那么您只需要将以上代码保存为 My-Script.cmd,放在同一个目录之下发给您的朋友即可。

这种方法还有个小小的好处是,不需要为不同的 .ps1 而修改 .cmd 的内容。

用批处理文件做一个简单的菜单,列出 .ps1 文件

该方法由 @PS 网友提供。优点在于可以为多个 .ps1 脚本配一个 .cmd 批处理。执行 .cmd 以后,将显示一个简易的字符界面选择菜单。可以根据用户的选择执行相应的 .ps1 脚本。以下是代码:

@echo off
setlocal enabledelayedexpansion
for  %%i in (*.ps1) do (
     set /a num+=1
     set .!num!=%%i
     echo !num!. %%i
)
set/p n=这里输入序列:
echo !.%n%!
set Path=%Path%;%SystemRoot%\system32\WindowsPowerShell\v1.0\ & powershell -ExecutionPolicy Unrestricted -NoProfile .\!.%n%!
pause

用命令行修改 PowerShell 文件的打开方式

该方法由 @史瑞克 网友提供,只需要在命令行中执行一次以下代码,以后即可双击运行 .ps1 脚本:

ftype Microsoft.PowerShellScript.1="%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe" ".\%1"

用这种方法可以设置打开方式和默认打开方式,需要管理员权限。恢复方法:

ftype Microsoft.PowerShellScript.1="%SystemRoot%\system32\notepad.exe" "%1"

用 PowerShell 脚本修改 PowerShell 文件的打开方式

该方法由 StackOverflow 上的 @JPBlanc 网友提供。只需要在 PowerShell 中执行一次以下代码,以后即可双击运行 .ps1 脚本。优点是可以开可以关。原文是法文,已由 @Andy Arismendi 网友翻译为英文。

<#
.SYNOPSIS
    Change the registry key in order that double-clicking on a file with .PS1 extension
    start its execution with PowerShell.
.DESCRIPTION
    This operation bring (partly) .PS1 files to the level of .VBS as far as execution
    through Explorer.exe is concern.
    This operation is not advised by Microsoft.
.NOTES
    File Name   : ModifyExplorer.ps1
    Author      : J.P. Blanc - jean-paul_blanc@silogix-fr.com
    Prerequisite: PowerShell V2 on Vista and later versions.
    Copyright 2010 - Jean Paul Blanc/Silogix
.LINK
    Script posted on:
    http://www.silogix.fr
.EXAMPLE
    PS C:\silogix> Set-PowAsDefault -On
    Call Powershell for .PS1 files.
    Done !
.EXAMPLE
    PS C:\silogix> Set-PowAsDefault
    Tries to go back
    Done !
#>
function Set-PowAsDefault
{
  [CmdletBinding()]
  Param
  (
    [Parameter(mandatory=$false,ValueFromPipeline=$false)]
    [Alias("Active")]
    [switch]
    [bool]$On
  )

  begin
  {
    if ($On.IsPresent)
    {
      Write-Host "Call Powershell for .PS1 files."
    }
    else
    {
      Write-Host "Try to go back."
    }
  }

  Process
  {
    # Text Menu
    [string]$TexteMenu = "Go inside PowerShell"

    # Text of the program to create
    [string] $TexteCommande = "%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command ""&'%1'"""

    # Key to create
    [String] $clefAModifier = "HKLM:\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open\Command"

    try
    {
      $oldCmdKey = $null
      $oldCmdKey = Get-Item $clefAModifier -ErrorAction SilentlyContinue
      $oldCmdValue = $oldCmdKey.getvalue("")

      if ($oldCmdValue -ne $null)
      {
        if ($On.IsPresent)
        {
          $slxOldValue = $null
          $slxOldValue = Get-ItemProperty $clefAModifier -Name "slxOldValue" -ErrorAction SilentlyContinue
          if ($slxOldValue -eq $null)
          {
            New-ItemProperty $clefAModifier -Name "slxOldValue" -Value $oldCmdValue  -PropertyType "String" | Out-Null
            New-ItemProperty $clefAModifier -Name "(default)" -Value $TexteCommande  -PropertyType "ExpandString" | Out-Null
            Write-Host "Done !"
          }
          else
          {
            Write-Host "Already done !"
          }

        }
        else
        {
          $slxOldValue = $null
          $slxOldValue = Get-ItemProperty $clefAModifier -Name "slxOldValue" -ErrorAction SilentlyContinue
          if ($slxOldValue -ne $null)
          {
            New-ItemProperty $clefAModifier -Name "(default)" -Value $slxOldValue."slxOldValue"  -PropertyType "String" | Out-Null
            Remove-ItemProperty $clefAModifier -Name "slxOldValue"
            Write-Host "Done !"
          }
          else
          {
            Write-Host "No former value !"
          }
        }
      }
    }
    catch
    {
      $_.exception.message
    }
  }
  end {}
}

使用方法很简单,Set-PowAsDefault -On为打开,Set-PowAsDefault为关闭。需要管理员权限。

以上是目前搜集的几种方法,希望对您有用。您可以在这里下载以上所有脚本的例子。

定时休眠的命令

例如2个小时以后休眠:

timeout /t 7200 /nobreak & shutdown /h

注意事项:

  1. shutdown /h /t xxx 这样的组合是没用的。
  2. 注意倒计时过程中不能按 CTRL+C 组合键来中止倒计时,否则会立即休眠。正确中止倒计时的方法是直接关闭命令行窗口。