0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ファイル名変更(候補をgoogle検索).ps1

Posted at

1. スクリプト概要

スクリプト名: ファイル名変更(候補をgoogle検索).ps1
現在のファイル名の一部でGoogle検索を行い、検索結果を元にファイル名を変更します

2. 処理と目的

処理の流れ
 1. ファイル名変更の対象となるファイルのフルパスを指定します
 2. 指定されたファイル名から検索ワードの候補を抽出します
 3. 抽出された検索ワード候補の中から、ユーザーが選択します
 4. 選択された文字列を使用してGoogle Custom Search APIで検索を実行します
 5. 検索結果のが表示されます
 6. ユーザーがクリップボードにコピーした文字列をファイル名に追記して、ファイル名を変更します

目的
アルファベットで短縮表記されたファイル名に日本語の情報を追加する際の作業効率化を目的としています

3. 動作環境と要件

PowerShellのバージョン
7.0以上

OS
Windows10

必要なモジュール
特になし

必要な権限
特になし

その他の設定
特になし

4. 使用方法

基本的な実行方法
スクリプトコードを拡張子ps1で保存してPowershellで実行してください。
ファイルを保存する際は、文字コードをUTF8 BOM付にしてください。

パラメータ
なし

使用例

  1. コマンドラインでpwsh ファイル名変更(候補をgoogle検索).ps1"を実行
  2. 対象ファイルのパスを求められるので、ファイルのフルパスを入力します
  3. 検索文字列を選択し、「OK」ボタンをクリックします
  4. ファイル名に追記したい文字列をクリップボードにコピーして処理を進めます

5. スクリプトコード

$host.UI.RawUI.WindowTitle = ([IO.Path]::GetFilenameWithoutExtension($PSCommandPath))
$ErrorActionPreference = 'Stop'

# Webユーティリティ機能を使用するためにSystem.Webアセンブリをロードします。
Add-Type -AssemblyName System.Web
# Windowsフォーム機能(クリップボード操作、GridViewなど)を使用するためにSystem.Windows.Formsアセンブリをロードします。
Add-Type -AssemblyName System.Windows.Forms

# Google Custom Search APIのエンドポイントURLを設定します。
$customSearchUrl = "https://www.googleapis.com/customsearch/v1"
# Google Custom Search APIのAPIキーを設定します。# ご自身のAPIキーに置き換えてください。
$apiKey = ''
# Google Custom Search EngineのID(cx)を設定します。# ご自身のCustom Search Engine IDに置き換えてください。
$customSearchId = ''

# メインループ。ファイル名変更処理を繰り返し実行します。
:mainloop while($true){
  echo "------------------------------------------------------------"
  do {
    # ユーザーに変更対象のファイルパスを入力するよう促します。
    $filePath = Read-Host "名称変更対象のファイルパス"
    # 入力されたパスから引用符(")を削除します。
    $filePath = $filePath.Trim('"')
  } while( $filePath -eq '' -or -not (Test-Path -literal $filePath) ) # ファイルパスが空でない、かつ、ファイルが存在するまで入力を繰り返します。
  $fileProp = gi -literal $filePath
  echo "「$($fileProp.Fullname)」のファイル名を変更します"

#############################
  $filename = $fileProp.BaseName
  # ファイル名をスペース、ピリオド、ハイフン、アンダースコア、アットマーク、角括弧、丸括弧で分割し、検索ワードの候補とします。
  $splitStr = [System.Text.RegularExpressions.Regex]::Split($filename,'\s|\.|-|_|@|\[|\]\(\)')
  # 検索ワードの候補を格納する配列を初期化します。
  $searchWords = @()

  # 分割された文字列から1~3単語の組み合わせを生成し、検索ワード候補とします。
  foreach( $len in (1..3) ){
    foreach( $searchIndex in (0..($splitStr.Length-$len-0))){
      $searchRegList =  @()
      foreach($i in ($searchIndex..($searchIndex+$len-1))){
        # 各単語を正規表現としてエスケープします。
        $searchRegList +=[System.Text.RegularExpressions.Regex]::Escape($splitStr[$i])
      }
      # 単語をピリオドで結合して正規表現パターンを作成します。(例: word1.word2)
      $searchRegex = [String]::Join('.',$searchRegList)
      #echo "searchRegex=${searchRegex}" # デバッグ用コメント
      # 作成した正規表現パターンでファイル名を検索します。
      $smt = [System.Text.RegularExpressions.Regex]::Match($filename,$searchRegex)
      # マッチした値が空でない場合、検索ワード候補に追加します。
      if(-not ([String]::IsNullOrEmpty($smt.Value))){
        $searchWords += $smt.Value
      }
    }
  }
  # 生成された検索ワード候補をグリッドビューで表示し、ユーザーに単一の検索ワードを選択させます。
  $searchWord = $searchWords | Out-GridView -Title '検索ワードを選択してください' -OutputMode Single
  # ユーザーが検索ワードを選択しなかった場合(グリッドビューをキャンセルした場合)、メインループの次へスキップします。
  if([String]::IsNullOrEmpty($searchWord)){
    continue
  }
  echo "選択された検索ワード=「${searchWord}」"

  # Google Custom Search APIのリクエストパラメータをセットします。
  $searchparam = @{}
  # 検索クエリをURLエンコードして設定します。
  $searchparam['q'] =  [System.Web.HttpUtility]::UrlEncode($searchWord)
  # Custom Search Engine IDを設定します。
  $searchparam['cx'] = $customSearchId
  # 検索言語を日本語に設定します。
  $searchparam['lr'] = "lang_ja"
  # 取得する検索結果の数を10件に設定します。
  $searchparam['num'] = 10
  # 検索結果の開始位置を0に設定します(最初の結果から)。
  $searchparam['start'] = 0
  # APIキーを設定します。
  $searchparam['key'] = $apiKey

  # 構築したパラメータをクエリ文字列としてURLに追加します。
  $url = $customSearchUrl + '?' + ( ($searchparam.Keys | %{"$($_)=$($searchparam[$_])"}) -join '&' )
  # 構築されたAPIリクエストURLを表示します。
  echo $url

  # Google Custom Search APIにリクエストを送信し、結果を取得します。
  $searchRes = Invoke-WebRequest $url
  # 取得したJSON形式のレスポンスをPowerShellオブジェクトに変換します。
  $seachData = $searchRes.Content | ConvertFrom-Json

  # 検索結果のタイトルとスニペット(概要)をフォーマットして表示します。
  $seachData.items | fl -Property @('title','snippet') | Out-Default
  echo "追記する文字列をコピーしてください"
  pause

  # ファイル名変更の確認ループ。
  do {
    # クリップボードからテキストデータを取得します。
    $appendText = [System.Windows.Forms.Clipboard]::GetDataObject().GetData([System.Windows.Forms.DataFormats]::Text)
    # ファイル名に使用できない不正な文字をスペースに置換します。
    foreach( $invalidChar in ([IO.Path]::GetInvalidFileNameChars())){
      $appendText = $appendText.replace($invalidChar,' ')
    }

    # 新しいファイル名を構築します: 元のファイル名(拡張子なし) + 半角スペース + クリップボードの文字列 + 拡張子。
    $newName = "$($fileProp.BaseName) $($appendText)$($fileProp.Extension)"
    # 複数連続するスペースを1つのスペースに置換します。
    $newName = $newName -replace ' +',' '
    # ファイル名の先頭と末尾のスペースを削除します。
    $newName = $newName.trim()

    echo "`n" # 改行を挿入します。
    # 変更後の新しいファイル名を表示します。
    echo "変更後名称:${newName}"

    # ユーザーにファイル名変更の確認を求めます。
    $ans = Read-Host "上記のファイル名に変更しますか?(y1/n0/skip)"

    # ユーザーが 'y' または '1' を入力した場合、ループを抜けてファイル名を変更します。
    if( $ans -in ('y','1')){
      break
    } # ユーザーが 'skip' を入力した場合、現在のファイルをスキップし、メインループの次の処理へ進みます。
    elseif ($ans -eq 'skip'){
      echo "このファイルをスキップして次にします。"
      continue mainloop
    } # ユーザーが 'n' またはその他の入力をした場合、再度クリップボードにコピーするよう促し、ループを続けます。
    else {
      echo "追記する文字列をコピーしてください"
      pause
    }
  } while($true) # 無限ループ(ユーザーが有効な選択をするかスキップするまで)

  # ファイル名を実際に変更します。
  ren -literal $fileProp.fullname $newName
  Write-Host "ファイル名を「$($fileProp.name)」→「$($newName)」にしました" -ForegroundColor Cyan

  pause
}

6. 注意事項と既知の問題

制約事項
追記名称候補はあくまでgoogle検索なので、常に適切な候補が含まれるとは限りません。

既知のバグ
もしバグを発見された場合は、コメントでご報告ください。

トラブルシューティング
・ps1ファイルのエンコーディングには注意してください。

7. 免責事項

本スクリプトにはいかなる保証もありません。使用は自己責任で行ってください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?