mongodb 学习路线

MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

mongodb

入门文章

电子书籍

工具

Robomongo

  • MongoVUE - 收费,Windows,体验略次。

MongoVUE - different views of the data

纸质书籍

MongoDB权威指南

AngularJS 学习路线

AngularJS 是Google开源的一款JavaScript MVC框架,弥补了HTML在构建应用方面的不足,诞生以来吸引了大量的目光,也迅速成为了Web开发领域的新宠。

AngularJS

网站

博客

入门

官方使用指南

w3school

链接合集

请展开看以下链接内容*

DEMO 项目

参考手册

视频教程

纸质书籍

用AngularJS开发下一代Web应用

图表

  • 一张图告诉你Angular的内核结构
    一张图告诉你Angular的内核结构

指令收藏(Directives)

  • jirikavi/AngularJS-Toaster - AngularJS Toaster is a customized version of “toastr” non-blocking notification javascript library.

用 PowerShell 批量分割 QQ 聊天记录

纯文本文件有诸多的好处:

  • 通用
  • 易于管理
  • 易于搜索
  • 易于迁移

接下来我们用 PoewrShell 来处理 QQ 的聊天记录。目的是将所有的聊天记录按照“组名/对象名.txt”来分别保存每个好友、每个 QQ 群等的聊天记录。

我现在用的是 QQ 6.1 (11905) 版本。依次打开 QQ / 工具 / 消息管理器,点击右上角的倒三角按钮可以看到“导出全部消息记录”菜单项。我们在接下来的对话框里的保存类型中选择“文本文件(*.txt,不支持导入)”,并用默认的“全部消息记录.txt”文件名保存。保存之后的文件内容大概是如下格式:

消息记录(此消息记录为文本格式,不支持重新导入)

================================================================
消息分组:我的好友
================================================================
消息对象:Victor.Woo
================================================================

2010-01-06 16:57:28 Victor.Woo
http://pic4.nipic.com/20090728/1684061_175750076_2.jpg

2010-05-27 12:29:35 Victor.Woo
6块钱包月55
8000/月
中心端,用户端

================================================================
消息分组:技术.关注
================================================================
消息对象:*PowerShell技术交流
================================================================

2013-06-23 15:52:32 此消彼长,云过有痕<qq_g@163.com>
http://yun.baidu.com/buy/center?tag=4#FAQ02

百度亮了,自己找亮点

2013-06-23 18:42:35 Victor.Woo<victorwoo@gmail.com>
[表情]

观察它的规律:

  • ================================================================ 作为每一段的元数据开始。
  • 接下来依次是消息分组、分隔符、消息对象。
  • ================================================================ 作为元数据的结束。
  • 元数据之后,是正文部分,直到下一个元数据开始。
  • 文件头部还有两行无关内容。
  • 文件尺寸巨大,不适合整体用正则表达式来提取,只能一行一行解析。

我们的目标是生成 我的好友/Victor.Woo.txt技术.关注/.PowerShell技术交流.txt

根据这个规律,我们可以用类似“状态机”的思想来设计 PowerShell 脚本。在遍历源文件的所有行时,用一个 $status 变量来表示当前的状态,各个状态的含义如下:

状态 含义
INIT 初始状态
ENTER_BLOCK 进入一个元数据块
ENTER_GROUP “消息分组”解析完成
ENTER_SPLITTER 元数据中间的分隔符解析完成
ENTER_TARGET “消息对象”解析完成
LEAVE_BLOCK 元数据块解析完成
CONTENT 当前行是正文内容

然后用一个 switch 语句让 $status 变量在这些状态之间来回跳转,就能解析出一个一个独立的消息文件了。完整代码如下:

function Get-Status($status, $textLine, $lineNumber, $block) {
    $splitter = '================================================================'
    switch ($status) {
        'INIT' {
            if ($textLine -eq $splitter) {
                $status = 'ENTER_BLOCK'
            }
        }
        'ENTER_BLOCK' {
            if ($textLine -cmatch '消息分组:(.*)') {
              $block.Group = $matches[1]
                $block.Target = $null
                $status = 'ENTER_GROUP'
                break
            } else {
              Write-Error "[$lineNumber] [$status] $textLine"
                exit
            }
        }
        'ENTER_GROUP' {
            if ($textLine -eq $splitter) {
                $status = 'ENTER_SPLITTER'
                break
            } else {
                Write-Error "[$lineNumber] [$status] $textLine"
                exit
            }
        }
        'ENTER_SPLITTER' {
            if ($textLine -cmatch '消息对象:(.*)') {
              $block.Target = $matches[1]
                $status = 'ENTER_TARGET'
                break
            } else {
              Write-Error "[$lineNumber] [$status] $textLine"
                exit
            }
        }
        'ENTER_TARGET' {
            if ($textLine -eq $splitter) {
                $status = 'LEAVE_BLOCK'
                break
            } else {
                Write-Error "[$lineNumber] [$status] $textLine"
                exit
            }
        }
        'LEAVE_BLOCK' {
            if ($textLine -eq $splitter) {
                $status = 'ENTER_BLOCK'
                break
            } else {
                $status = 'CONTENT'
            }
        }
        'CONTENT' {
            if ($textLine -eq $splitter) {
                $status = 'ENTER_BLOCK'
                break
            } else {
                $status = 'CONTENT'
            }
        }
    }

    return $status
}

$status = 'INIT'
$lineNumber = 0
$block = @{}
$targetPath = $null
cat 全部消息记录.txt -Encoding UTF8 | foreach {
    $textLine = $_
    $lineNumber++
    $status = Get-Status $status $textLine $lineNumber $block
    switch ($status) {
        'LEAVE_BLOCK' {
            if ($block.Target -eq '最近联系人') {
                break
            }
            $dirName = $block.Group.Replace('*', '.')
            if (!(Test-Path $dirName)) {
                md $dirName | Out-Null
            }

            $fileName = $block.Target.Replace('*', '.')

            $targetPath = (Join-Path $dirName $fileName) + '.txt'
            if (Test-Path $targetPath) {
                del $targetPath
            }

            echo $targetPath
        }
        'CONTENT' {
            #echo $textLine
            if ($block.Target -eq '最近联系人') {
                break
            }
            Out-File -InputObject $textLine -Encoding utf8 -LiteralPath $targetPath -Append
        }
    }
}

您也可以在这里下载完成后的版本。

PowerShell 技能连载 - 查找 AD 用户

适用于所有 PowerShell 版本

假如您已登录到了一个活动目录域中,那么只需要执行一些简单的命令就可以搜索活动目录。在前一个技巧中我们演示了最基本的脚本。以下是一个扩展,它能够定义一个搜索的根(搜索的起点),就像一个扁平的搜索一样(相对于在容器中递归而言)。

它也演示了如何将活动目录的搜索结果转换成实际的用户对象:

$SAMAccountName = 'tobias'
$SearchRoot = 'LDAP://OU=customer,DC=company,DC=com'
$SearchScope = 'OneLevel'

$ldap = "(&(objectClass=user)(samAccountName=*$SAMAccountName*))"
$searcher = [adsisearcher]$ldap
$searcher.SearchRoot = $SearchRoot
$searcher.PageSize = 999
$searcher.SearchScope = $SearchScope

$searcher.FindAll() |
  ForEach-Object { $_.GetDirectoryEntry()  } |
  Select-Object -Property *

PowerShell 技能连载 - 查找并提取注册表键的路径

适用于所有 PowerShell 版本

在前一个技巧中,我们演示了如何将一个 PowerShell 内部的路径格式转换为一个真实的路径。以下是一个用力。这段代码递归地搜索 HKEY_CURRENT_USER 键,并且找出所有包含单词“_powershell_”的注册表键(您可以将搜索关键字换成任何别的):

Get-ChildItem -Path HKCU:\ -Include *PowerShell* -Recurse -ErrorAction SilentlyContinue |
  Select-Object -Property *Path* |
  Out-GridView

这段代码输出所有名称中包含“Path_”的属性。如您所见,注册表键中有两个属性包含该关键字:_PSPath 和 _PSParentPath_。两者都是 PowerShell 内置的路径格式。

要提取所有满足搜索条件的注册表键的路径,请使用以下代码:

Get-ChildItem -Path HKCU:\ -Include *PowerShell* -Recurse -ErrorAction SilentlyContinue |
  ForEach-Object {
    Convert-Path -Path $_.PSPath
  }

PowerShell 技能连载 - 修正 PowerShell 中的路径

适用于所有 PowerShell 版本

有些时候,您会为某些奇怪的路径格式感到困惑,比如这个:

Microsoft.PowerShell.Core\FileSystem::C:\windows\explorer.exe

这是一个完整的 PowerShell 路径名,路径中包含了了模块名和提供器名。要得到一个纯的路径名,请使用以下代码:

Convert-Path -Path Microsoft.PowerShell.Core\FileSystem::C:\windows\explorer.exe

PowerShell 技能连载 - 修正名单中的大小写

适用于所有 PowerShell 版本

假设您的工作是更新一份名单。以下方法可以确保只有名字的第一个字母改成大写。这个方法对于姓-名的方式也是有效的:

$names = 'some-wILD-casING','frank-PETER','fred'

Foreach ($name in $names)
{
  $corrected = foreach ($part in $name.Split('-'))
  {
    $firstChar = $part.Substring(0,1).ToUpper()
    $remaining = $part.Substring(1).ToLower()

    "$firstChar$remaining"
  }
  $corrected -join '-'
}

Some-Wild-Casing
Frank-Peter
Fred

PowerShell 技能连载 - 使系统休眠

适用于 PowerShell 所有版本

以下是一个简单的系统调用,可以使系统休眠(当然,前提是启用了休眠功能):

function Start-Hibernation
{
  rundll32.exe PowrProf.dll, SetSuspendState 0,1,0
}

请注意这个函数调用是大小写敏感的!

PowerShell 技能连载 - 指定递归深度

适用于 PowerShell 3.0 及更高版本

当使用 Get-ChildItem 来列出文件夹内容时,可以用 -Recurse 参数来对子目录进行递归。然而,这导致无法控制递归深度。Get-ChildItem 会在所有子目录中搜索,无限地递归下去。

Get-ChildItem -Path $env:windir -Filter *.log -Recurse -ErrorAction SilentlyContinue

有些时候,我们会见到一种类似这样的方法,来试图控制递归的深度:

Get-ChildItem -Path $env:windir\*\*\* -Filter *.log -ErrorAction SilentlyContinue

然而,这并不能限制只递归 3 层。实际上,它的作用是搜索 3 层及 3 层以上的文件夹。它不会搜索 1 层或 2 层的文件夹。

限制递归深度的唯一办法是自己实现递归算法:

function Get-MyChildItem
{
  param
  (
    [Parameter(Mandatory = $true)]
    $Path,

    $Filter = '*',

    [System.Int32]
    $MaxDepth = 3,

    [System.Int32]
    $Depth = 0
  )

  $Depth++

  Get-ChildItem -Path $Path -Filter $Filter -File

  if ($Depth -le $MaxDepth)
  {
    Get-ChildItem -Path $Path -Directory |
      ForEach-Object { Get-MyChildItem -Path $_.FullName -Filter $Filter -Depth $Depth -MaxDepth $MaxDepth}
  }

}

Get-MyChildItem -Path c:\windows -Filter *.log -MaxDepth 2 -ErrorAction SilentlyContinue |
  Select-Object -ExpandProperty FullName

这段代码将获取您 Windows 文件夹中深度在 2 层以内的 *.log 文件。