質問

多数のファイルを検索する小さなユーティリティがあります。 GoogleとWindowsのデスクトップ検索の両方がファイルに適切な行が見つからなかったため、作成する必要がありました。検索は正常に機能します(私はそれを改善したいと思っています)が、UTILに追加したいことの1つは、バッチ検索/交換です。

では、ファイルから行を読み取り、検索用語と比較し、それが渡された場合、行を更新し、ファイルの残りの部分を継続するための最良の方法はどのようになりますか?

役に立ちましたか?

解決

私は各ファイルに対して次のことをします:

  • 通常どおり検索を行います。また、トークンをチェックして交換してください。あなたがそれを見たらすぐに、そのファイルをもう一度開始します。交換するトークンが表示されない場合は、完了です。
  • もう一度起動するときは、新しいファイルを作成し、入力ファイルから読み取る各行をコピーして、行くときに交換を行います。
  • ファイルが終わったら:
    • 現在のファイルをバックアップファイル名に移動します
    • 新しいファイルを元のファイル名に移動します
    • バックアップファイルを削除します

ただし、バイナリファイルなどでこれを行わないように注意してください。テキスト検索を行い、バイナリファイルで交換する結果は通常悲惨です。

他のヒント

PowerShellがオプションである場合、以下に定義する関数を使用して、ファイル全体で検索と交換を実行できます。たとえば、見つけるには 'a string' 現在のディレクトリのテキストファイルでは、次のことを行います。

dir *.txt | FindReplace 'a string'

交換する 'a string' 別の値を使用すると、最後に新しい値を追加するだけです。

dir *.txt | FindReplace 'a string' 'replacement string'

単一のファイルでそれを使用して呼び出すこともできます FindReplace -path MyFile.txt 'a string'.

function FindReplace( [string]$search, [string]$replace, [string[]]$path ) {
  # Include paths from pipeline input.
  $path += @($input)

  # Find all matches in the specified files.
  $matches = Select-String -path $path -pattern $search -simpleMatch

  # If replacement value was given, perform replacements.
  if( $replace ) {
    # Group matches by file path.
    $matches | group -property Path | % {
      $content = Get-Content $_.Name

      # Replace all matching lines in current file.
      foreach( $match in $_.Group ) {
        $index = $match.LineNumber - 1
        $line = $content[$index]
        $updatedLine = $line -replace $search,$replace
        $content[$index] = $updatedLine

        # Update match with new line value.
        $match | Add-Member NoteProperty UpdatedLine $updatedLine
      }

      # Update file content.
      Set-Content $_.Name $content
    }
  }

  # Return matches.
  $matches
}

ご了承ください Select-String また、正規表現の一致をサポートしていますが、シンプルさのために簡単なマッチに制約されています。) ジョン 新しいコンテンツでファイルを上書きするだけでなく、提案しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top