定时休眠的命令
例如2个小时以后休眠:
timeout /t 7200 /nobreak & shutdown /h
注意事项:
shutdown /h /t xxx
这样的组合是没用的。- 注意倒计时过程中不能按
CTRL+C
组合键来中止倒计时,否则会立即休眠。正确中止倒计时的方法是直接关闭命令行窗口。
例如2个小时以后休眠:
timeout /t 7200 /nobreak & shutdown /h
注意事项:
shutdown /h /t xxx
这样的组合是没用的。CTRL+C
组合键来中止倒计时,否则会立即休眠。正确中止倒计时的方法是直接关闭命令行窗口。本来开始打算大干一场的,结果发现区区4行代码搞定了。原来用PowerShell统计关键词这么欢乐啊。
$wordBreakers = ",. ()\\/';-<>_#"
$wordTemplate = '^Pub\w+'
cd D:\Dropbox\workdir\LandiStore\BOCISTDemo\src\Project
$content = (dir *.c -Recurse | % { cat $_} ) -join "`n"
$words = $content.Split($wordBreakers)
$words = $words | ? {$_ -Match $wordTemplate}
#$words | sort -Unique
$words | group | sort count -Descending | select Name, Count
计划写一系列整理文件用的脚本。例如根据id3来对mp3文件归档、根据exif信息来对照片归档、根据verycd上的资源名称对下载的文件归档……
这时候会遇到一个问题:Windows的文件系统是不允许某些特殊字符,以及设备文件名的。详细的限制请参见:http://zh.wikipedia.org/wiki/%E6%AA%94%E6%A1%88%E5%90%8D%E7%A8%B1。
这个PowerShell脚本帮助你避开这些坑。具体的做法是将特殊字符替换成’.’,对于恰好是设备名称的主文件名或扩展名之前添加’_’。
function Get-ValidFileSystemName
{
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string]$FileSystemName
)
process{
$deviceFiles = 'CON', 'PRN', 'AUX', 'CLOCK$', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($FileSystemName)
$extension = [System.IO.Path]::GetExtension($FileSystemName)
if ($extension.StartsWith('.'))
{
$extension = $extension.Substring(1)
}
if ($deviceFiles -contains $fileName)
{
$fileName = "_$fileName"
}
if ($deviceFiles -contains $extension)
{
$extension = "_$extension"
}
if ($extension -eq '')
{
$FileSystemName = "$fileName$extension"
}
else
{
$FileSystemName = "$fileName.$extension"
}
$FileSystemName = $FileSystemName -creplace '[\\/|?"*:<>\x00\x1F\t\r\n]', '.'
return $FileSystemName
}
}
流水不腐,户枢不蠹。虽然批量下载有很多工具能做到,但是为了提高,我们尽量动手编写脚本吧。
http://www.cheat-sheets.org 里有很多好东西,我们把它批量下载下来。
PowerShell代码:
Add-Type -AssemblyName System.Web
$baseUrl = 'http://www.cheat-sheets.org'
$result = Invoke-WebRequest $baseUrl
$result.Links |
? {$_.href -Like '*.pdf'} |
select -ExpandProperty href |
sort |
% {
if ($_ -like '/*')
{
$baseUrl + $_
} else {
$_
}
} |
% {
echo "Downloading $_"
$fileName = $_.Substring($_.LastIndexOf("/") + 1)
$localFileName = [System.Web.HttpUtility]::UrlDecode($fileName)
if (Test-Path $localFileName) {
return
}
Invoke-WebRequest -Uri $_ -OutFile $localFileName
if (Test-Path $localFileName) {
Unblock-File $localFileName
}
}
以下是我个人的PowerShell学习路线,也许可以节省您一些走弯路的时间,供参考。
Windows Powershell入门指南(中文)-微软资料.pdf
- 篇幅很短,仅 29 页,入门找感觉,一天即可读完。pstips.chm
- 中文电子书,篇幅适中,涵盖了语法要点,重点推荐!推荐打印出来放案头备用。
Windows PowerShell 语言快速参考.rtf
- 只有三页纸的速查表(中文)powershell_reference_Apr2010.doc
- 只有两页纸的速查表(英文)WindowsPowerShellHelp_官方手册.chm
- 微软官方,浏览一下有哪些内容,日后备用。[Windows.PowerShell.Pocket.Reference(2nd,2012.12)].Lee.Holmes.文字版.pdf
- 系统学习用,可以一周读完,后几章可跳过,100 来页。[Windows.Powershell.实战(第2版)].(Windows.Powershell.in.Action).Bruce.Payette.文字版.pdf
- 经典,深入学习用,900 来页,可以用来当工具书查阅。所有 PowerShell 电子书的合集,自动更新:《PowerShell 电子书合集》
pstips.chm
实际上是 PowerShell 在线教程 的离线版。例如csdn下载的一个文件名字为 %5B大家网%5DWindows.PowerShell应用手册%5Bwww.TopSage.com%5D.pdf
,我们通过两行PowerShell脚本把它转化为正常的 [大家网]Windows.PowerShell应用手册[www.TopSage.com].pdf
。量大的时候特别好用。
方法如下:
Add-Type -AssemblyName System.Web
dir | % { ren -LiteralPath $_ ([System.Web.HttpUtility]::UrlDecode($_)) }
这是花了一个晚上写的PowerShell脚本,可以把你的目录以GTD的思想整理得井井有条。
但是GTD功能已经完整并通过测试。github地址:victorwoo/Get-ThingsDone。
不了解GTD的同学请参考以下材料:
[《搞定》中文版] 1、[《Get Things Done》英文版] 2
#========================================================================
# Created on: 2013-3-7 16:21
# Created by: Victor.Woo
# Organization: www.vichamp.com
# Filename: Get-ThingsDone.ps1
#========================================================================
function Check-Enviroment
{
$gtdPath = "HKCU:\Software\Vichamp\GTD"
if ((Get-ItemProperty $gtdPath -ErrorAction SilentlyContinue).AutoStart -eq "False")
{
return
}
$runPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
$run = Get-ItemProperty $runPath
if ($run.GTD -eq $null)
{
$title = '自动执行请求'
$message = '在当前 Windows 用户登录时自动运行此脚本,可以自动帮助您整理、规划当日的工作内容。如果您选择了“是”,但将来不希望自动启动,请执行 uninstall.cmd。是否在当前用户登录时自动执行脚本?'
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes","Windows 用户登录时自动运行此脚本。"
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No","Windows 用户登录时不运行此脚本,并且不再提示。"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)
$result = $Host.UI.PromptForChoice($title,$message,$options,0)
switch ($result)
{
0 {
Set-ItemProperty -Path $runPath -Name GTD -Value $gtdCmd
}
1 {
md $gtdPath -Force
Set-ItemProperty -Path $gtdPath -Name AutoStart -Value "False"
}
}
}
}
function TryCreate-Directory ([Parameter(Mandatory = $True)] [string]$dirName)
{
$private:dir = Join-Path $baseDir $dirName
if (-not (Test-Path $dir))
{
Write-Output "$dir 不存在,正在创建。"
mkdir $dir | Out-Null
}
}
function TryCreate-Directories ()
{
Write-Output "正在检查目录完整性"
$dirNames |
% {
TryCreate-Directory $_
}
}
function Remove-Directories ()
{
$dirNames |
% {
$private:dir = Join-Path $baseDir $_
if (Test-Path $dir)
{
Write-Warning "正在移除$dir"
rm $dir -Recurse
}
}
}
function MoveTo-WithRenamming (
[Parameter(Mandatory = $True)] [System.IO.FileSystemInfo]$item,
[Parameter(Mandatory = $True)] [string]$targetDir)
{
function Get-NextFilePath ([string]$dir,[System.IO.FileInfo]$fileInfo)
{
$Private:targetFilePath = Join-Path $dir $fileInfo.Name
if (Test-Path $Private:targetFilePath)
{
$Private:index = 1
do {
$Private:targetFilePath = Join-Path $dir "$($fileInfo.BaseName) ($index)$($fileInfo.Extension)"
$Private:index++
}
while (Test-Path $Private:targetFilePath)
}
return [System.IO.FileInfo]$Private:targetFilePath
}
function Get-NextDirectoryPath ([string]$dir,[System.IO.DirectoryInfo]$directoryInfo)
{
$Private:targetDirectoryPath = Join-Path $dir $directoryInfo.Name
if (Test-Path $Private:targetDirectoryPath)
{
$Private:index = 1
do {
$Private:targetDirectoryPath = Join-Path $dir "$($directoryInfo.Name) ($index)"
$Private:index++
}
while (Test-Path $Private:targetDirectoryPath)
}
return [System.IO.DirectoryInfo]$Private:targetDirectoryPath
}
Write-Output "正在移动 $item 至 $targetDir 目录"
if ($item -is [System.IO.FileInfo])
{
# 待移动的是文件
[System.IO.FileInfo]$item = [System.IO.FileInfo]$item
$Private:targetFilePath = Join-Path $targetDir $item.Name
if (Test-Path $Private:targetFilePath)
{
# 目标文件已存在
$targetFileInfo = [System.IO.FileInfo]$Private:targetFilePath
$Private:targetFilePath = Get-NextFilePath $targetDir $item
if ($item.LastWriteTime -eq $targetFileInfo.LastWriteTime -and $item.Length -eq $targetFileInfo.Length)
{
# 文件时间和大小相同
Write-Warning "源文件 $item.FullName 与目标文件 $targetFileInfo.FullName 相同,删除源文件"
Remove-Item $item.FullName
}
else
{
Write-Warning "目标文件已存在,自动改名为$($Private:targetFilePath.Name)"
Move-Item $item.FullName $Private:targetFilePath | Out-Null
}
}
else
{
# 目标文件不存在
if (!(Test-Path $targetDir))
{
# 目标目录不存在,创建目标目录
md $targetDir | Out-Null
}
Move-Item $item.FullName $Private:targetFilePath | Out-Null
}
} elseif ($item -is [System.IO.DirectoryInfo])
{
# 待移动的是目录
[System.IO.DirectoryInfo]$item = [System.IO.DirectoryInfo]$item
$Private:targetDirectoryPath = Join-Path $targetDir $item.Name
if (Test-Path $Private:targetDirectoryPath)
{
$Private:targetDirectoryPath = Get-NextDirectoryPath $targetDir $item
Write-Warning "目标文件夹已存在,自动改名为$($Private:targetDirectoryPath.Name)"
}
Move-Item $item.FullName $Private:targetDirectoryPath | Out-Null
}
}
function Process-IsolatedItems
{
Write-Output "正在将游离内容移至 [STUFF] 目录"
Get-ChildItem $baseDir -Exclude ($dirNames + $reservedDirs + $reservedFiles) |
% {
MoveTo-WithRenamming $_ $stuffDir
}
}
function Process-TomorrowDir
{
Write-Output "正在处理 [TOMORROW] 目录"
Get-ChildItem $tomorrowDir |
% {
MoveTo-WithRenamming $_ $todayDir
}
}
function Process-CalendarDir
{
Write-Output "正在处理 [CALENDAR] 目录"
Get-ChildItem $calendarDir -File |
% {
MoveTo-WithRenamming $_ $stuffDir
}
Get-ChildItem $calendarDir -Directory |
% {
$regex = [regex]'(?m)^(?<year>19|20\d{2})[-_.](?<month>\d{1,2})[-_.](?<day>\d{1,2})$'
$match = $regex.Match($_.Name)
if ($match.Success)
{
$Private:year = $regex.Match($_.Name).Groups['year'].Value;
$Private:month = $regex.Match($_.Name).Groups['month'].Value;
$Private:day = $regex.Match($_.Name).Groups['day'].Value;
$Private:date = New-Object System.DateTime $Private:year,$Private:month,$Private:day
$now = (Get-Date)
$today = $now.Subtract($now.TimeOfDay)
if ($date -lt $today)
{
Write-Output "移动过期任务 $($_.Name) 到 [STUFF] 目录"
MoveTo-WithRenamming $_ $stuffDir
}
elseif ($date -eq $today)
{
Write-Output "移动今日任务 $($_.Name) 到 [TODAY] 目录"
MoveTo-WithRenamming $_ $todayDir
}
elseif ($date -eq $today.AddDays(1))
{
Write-Output "移动明日任务 $($_.Name) 到 [TOMORROW] 目录"
MoveTo-WithRenamming $_ $tomorrowDir
}
}
else
{
Write-Output "[CALENDAR] 目录下,$($_.Name) 名字不符合规范,将移动至 [STUFF] 目录"
MoveTo-WithRenamming $_ $stuffDir
}
}
}
function Process-ArchiveDir
{
Write-Output "正在检查 [ARCHIVE] 目录"
# 创建本月目录
$nowString = "{0:yyyy.MM}" -f (Get-Date)
$thisMonthDir = Join-Path $archiveDir $nowString
if (-not (Test-Path $thisMonthDir))
{
Write-Output "正在创建本月目录"
md $thisMonthDir
}
# 移除除本月之外的空目录
Get-ChildItem $archiveDir -Exclude $nowString -Recurse |
Where { $_.PSIsContainer -and @( Get-ChildItem -LiteralPath $_.FullName -Recurse | Where { !$_.PSIsContainer }).Length -eq 0 } |
% {
Write-Output "正在删除空目录$($_.FullName)"
Remove-Item -Recurse
}
# 移动所有文件到 本月存档 目录
Get-ChildItem $archiveDir -File |
% {
$lastWriteTime = "{0:yyyy.MM}" -f $_.LastWriteTime
$lastWriteDir = Join-Path $archiveDir $lastWriteTime
Write-Output "移动 [ARCHIVE] 目录下,$($_.Name) 游离文件至 $lastWriteDir 存档目录"
MoveTo-WithRenamming $_ $lastWriteDir
}
# 检查目录命名是否符合规范。
Get-ChildItem $archiveDir -Directory |
% {
$regex = [regex]'(?m)^(?<year>19|20\d{2})[-_.](?<month>\d{1,2})$'
$match = $regex.Match($_.Name)
if ($match.Success)
{
# Archive目录下的名字符合格式
$year = $regex.Match($_.Name).Groups['year'].Value;
$month = $regex.Match($_.Name).Groups['month'].Value;
$date = New-Object System.DateTime $year,$month,1
if ($date -gt (Get-Date))
{
Write-Output "[ARCHIVE] 目录下,$($_.Name) 名字不符合规范(存档日期超出当前时间),将移动至 [STUFF] 目录"
MoveTo-WithRenamming $_ $stuffDir
}
else
{
$formattedDate = "{0:yyyy.MM}" -f $date
if ($_.Name -ne $formattedDate)
{
$targetDirectory = [System.IO.DirectoryInfo](Join-Path $_.Parent.FullName $formattedDate)
Write-Warning "将 [ARCHIVE] 下的目录名 $($_.Name) 处理为规范格式 $($targetDirectory.Name)"
Move-Item $_.FullName $targetDirectory.FullName
}
}
} else
{
# Archive目录下的名字符不合格式
$lastWriteTime = $nowString = "{0:yyyy.MM}" -f $_.LastWriteTime
$lastWriteDir = Join-Path $archiveDir $lastWriteTime
Write-Output "移动 [ARCHIVE] 目录下,$($_.Name) 游离文件夹至 $lastWriteDir 存档目录"
MoveTo-WithRenamming $_ $lastWriteDir
}
}
}
function Explore-Dirs
{
if ((Get-ChildItem $stuffDir) -ne $null)
{
explorer $stuffDir
}
if ((Get-ChildItem $todayDir) -ne $null)
{
explorer $todayDir
}
}
$STUFF = "1.STUFF"
$TODAY = "2.TODAY"
$TOMORROW = "3.TOMORROW"
$UPCOMING = "4.UPCOMING"
$CALENDAR = "5.CALENDAR"
$SOMEDAY = "6.SOMEDAY"
$ARCHIVE = "7.ARCHIVE"
$dirNames = $STUFF,$TODAY,$TOMORROW,$UPCOMING,$CALENDAR,$SOMEDAY,$ARCHIVE
$reservedDirs = ".git","_gsdata_"
$reservedFiles = ".gitignore","Get-ThingsDone.ps1","README*.md","gtd_logo.png","LICENSE.md","GTD.cmd","uninstall.cmd"
$baseDir = Split-Path $MyInvocation.MyCommand.Path
$stuffDir = Join-Path $baseDir $STUFF
$todayDir = Join-Path $baseDir $TODAY
$tomorrowDir = Join-Path $baseDir $TOMORROW
$calendarDir = Join-Path $baseDir $CALENDAR
$archiveDir = Join-Path $baseDir $ARCHIVE
$gtdCmd = Join-Path $baseDir "GTD.cmd"
Get-Date | Write-Output
Check-Enviroment
TryCreate-Directories
Process-IsolatedItems
Process-TomorrowDir
Process-CalendarDir
Process-ArchiveDir
Explore-Dirs
######################### 开发临时用(在 ISE 中选中并按 F8 执行) #########################
return
{
return
# 创建游离内容。
$null | Set-Content (Join-Path $baseDir "to.del.file.txt")
md (Join-Path $baseDir "to.del.dir") | Out-Null
}
{
return
# 对代码排版。
Import-Module D:\Dropbox\script\DTW.PS.PrettyPrinterV1\DTW.PS.PrettyPrinterV1.psd1
Edit-DTWCleanScript D:\Dropbox\vichamp\GTD\Get-ThingsDone.ps1
}
{
return
# 移除所有目录
Remove-Directories
}
在做嵌入式设备开发和调试工作中,可能常常遇到以下场景,需要把:
0000:60 00 00 00 00 00 00 00 00 00 00 42 00 00 18 00 `....... ...B....:0015
0016:01 80 80 00 03 14 20 24 20 11 08 17 08 12 34 56 ...... $ .....4V:0031
0032:78 08 87 65 43 21 36 35 30 34 31 37 31 38 00 59 x..eC!65 041718.Y:0047
0048:30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 00000000 00010000:0063
0064:30 30 30 30 49 43 41 52 44 30 30 30 30 30 30 30 0000ICAR D0000000:0079
0080:34 30 30 30 30 30 30 31 32 31 36 30 30 30 30 30 40000001 21600000:0095
0096:30 34 30 30 30 30 32 30 34 30 35 31 31 31 31 31 04000020 40511111:0111
0112:31 31 31 111 :0127
这样的文本,转换为单行,头尾部分不要,中间重复的空格也不要。如下:
60 00 00 00 00 00 00 00 00 00 00 42 00 00 18 00 01 80 80 00 03 14 20 24 20 11 08 17 08 12 34 56 78 08 87 65 43 21 36 35 30 34 31 37 31 38 00 59 30 30 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 49 43 41 52 44 30 30 30 30 30 30 30 34 30 30 30 30 30 30 31 32 31 36 30 30 30 30 30 30 34 30 30 30 30 32 30 34 30 35 31 31 31 31 31 31 31 31
这个可以用vim的替换来实现,命令是::%s/\d*:\(\(\x\|\s\)\{24}\) \(\(\x\|\s\)\{24}\).*\n/\1\3/g
我们还可以为它在.vimrc中定义一个快捷键映射:map <C-H> :%s/\d*:\(\(\x\\|\s\)\{24}\) \(\(\x\\|\s\)\{24}\).*\n/\1\3/g<CR>
这样以后按一下CTRL+H键就搞定了。