stgtの日記

思い付き、気になったことを覚えておけない。

ドキュメントをあさる際のあれこれ

目次

正規表現

コメント行検索

^.*//.*$
削除する場合は^.*//.*\r\nを置換

空白行検索

^\r\n
行先頭が改行コード

特定の文字列を含まない行を検索

^(?!.*test).*$
特定の文字列が「test」の場合
欲しい内容以外の行を削除する際に、
置換することで「test」を含まない行を削除

PowerShell

1.ファルダ内ファイル検索

再帰的に検索

$Name = "ファイル名"
Get-Childitem -File C:\src\ -r -Filter $Name | % {$_.Fullname}

上記結果をOut-Fileでファイルに出力し、
サクラエディタで開くとパスクリックでファイルを開けて便利

2.grep

上記のファイル検索と組み合わせて

Select-String "readme" (Get-Childitem -File C:\src\ -r)

3.ファイルを階層を保持してコピー

コピー元とコピー先のディレクトリを指定
ファイル検索し、コピー元指定ディレクトリ以降の構成でコピーする

コード

#$Arg1は「*.txt」とか「Readme*」とかコピーしたいファイル
Param(
    [parameter(mandatory=$true)][String]$Arg1,
    # コピー元
    [Parameter()][String]$Arg2 = "C:\Program` Files",
    # コピー先
    [Parameter()][String]$Arg3 = "C:\backup"
)

# C:\Program Files\App\readme.txt
# 引数指定以降のパスが取れる(App\readme.txt)
$src = Get-Childitem $Arg2 -r -Filter $Arg1 -Name

$src `
| %{ [PSCustomObject]@{
    Path = Join-Path $Arg2 $_
    Destination = Join-Path $Arg3 $_
    }}`
| %{
   
    # ディレクトリの存在しないパスに絶対パスを指定し、コピーをすると
    # エラーとなるため、最初にディレクトリ生成
    $DirectoryName = Split-Path -Parent $_.Destination
    New-Item $DirectoryName -ItemType Directory -Force

    # 同一階層にコピー
    Copy-Item -Path $_.Path -Destination $_.Destination -Force
    }
New
Param(
    [Parameter(Mandatory=$true)]
    [ValidateScript({Test-Path -LiteralPath $_ -PathType Container})]
    [String]
    $srcPath,
    [Parameter(Mandatory=$true)][String]
    $destPath,
    [Parameter(Mandatory=$true)][String]
    $filter
)

$null = New-Item $destPath -Force -ItemType Container

# C:\Program Files\App\readme.txt
# 引数指定以降のパスが取れる(App\readme.txt)
$obj = Get-ChildItem "${srcPath}" -Recurse -File -Filter "${filter}" -Name |`
    Select-Object -Property @{ Name = "src";  Expression = { Join-Path $srcPath $_ }},`
                            @{ Name = "dest"; Expression = { Join-Path $destPath $_ }},`
                            @{ Name = "name"; Expression = { Split-Path -Leaf $_ }},`
                            @{ Name = "type"; Expression = { if (Test-Path (Join-Path $destPath $_)) {
                                                                "上書き"
                                                             } else {
                                                                "新規  "
                                                             } }
                             }
#実行確認
###
Write-Host @"

以下、$(@($obj).Count)件のファイルをコピーします
"@
###

#ファイル情報出力
$obj | Sort-Object type | Format-Table type, name -AutoSize

###
[String]$response = Read-Host @"
【${srcPath}】
  →【${destPath}】

よろしいですか? (y/n)
"@
###

if ($response -ne "y") {
    Write-Host "処理を中断しました"
    exit
}

#ファイルコピー
$obj | %{
    $DirectoryName = Split-Path -Parent $_.dest
    if (!(Test-Path $DirectoryName)) {
        New-Item $DirectoryName -ItemType Directory -Force
    }
    # 同一階層にコピー
    Copy-Item -Path $_.src -Destination $_.dest -Force
}

Write-Host "Done"
srcPath: C:\src
destPath: C:\backup
filter: readme*

以下、3件のファイルをコピーします

type   name
----   ----
上書き Readme.txt
新規   Readme.txt
新規   README.md


【C:\src】
  →【C:\backup】

よろしいですか? (y/n): y

フルパスを表示したほうがいいかもしれない

結果

「readme*」を第一引数に与えて実行

C:\PROGRAM FILES
├─Test
│  └─Test Software
│          Readme.txt
│
├─WindowsPowerShell
│  └─Modules
│      └─Pester
│          └─3.4.0
│                  README.md
(省略)

C:\BACKUP
├─Test
│  └─Test Software
│          Readme.txt
│
└─WindowsPowerShell
   └─Modules
       └─Pester
           └─3.4.0
                   README.md