Leia e atualize filestream
-
19-08-2019 - |
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?
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.