Pergunta

Eu tenho um pequeno utilitário que faz uma pesquisa de vários arquivos. Eu tive que criá -lo porque as pesquisas de desktop do Google e do Windows não estavam encontrando as linhas apropriadas nos arquivos. A busca funciona bem (estou disposto a melhorar), mas uma das coisas que eu gostaria de adicionar ao meu Util é uma localização/substituição em lote.

Então, como seria a melhor maneira de ler uma linha de um arquivo, compará -la com um termo de pesquisa e, se ele passar, atualizar a linha e continuar pelo restante do arquivo?

Foi útil?

Solução

Eu faria o seguinte para cada arquivo:

  • Faça a pesquisa normalmente. Verifique também o token para substituir. Assim que você vir, inicie esse arquivo novamente. Se você não vê o token para substituir, terminou.
  • Ao começar de novo, crie um novo arquivo e copie cada linha que você leu no arquivo de entrada, fazendo a substituição à medida que avança.
  • Quando você terminar o arquivo:
    • Mova o arquivo atual para um nome de arquivo de backup
    • Mova o novo arquivo para o nome do arquivo original
    • Exclua o arquivo de backup

Tenha cuidado para que você não faça isso em arquivos binários, etc. - as consequências de fazer uma pesquisa textual e substituir em arquivos binários geralmente seriam terríveis!

Outras dicas

Se o PowerShell for uma opção, a função definida abaixo poderá ser usada para executar o encontro e substituição nos arquivos. Por exemplo, para encontrar 'a string' Nos arquivos de texto no diretório atual, você faria:

dir *.txt | FindReplace 'a string'

Para substituir 'a string' Com outro valor, basta adicionar o novo valor no final:

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

Você também pode chamá -lo em um único arquivo usando 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
}

Observe que Select-String também suporta correspondências de regex, mas foi restringido a correspondências simples de simplicidade;) você também pode realizar uma substituição mais robusta como Jon sugerido, em vez de apenas substituir o arquivo com o novo conteúdo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top