Substituindo texto no arquivo em determinada largura

Substituindo texto no arquivo em determinada largura

Como posso substituir em determinadas posições da coluna?

Exemplo: quero substituir as colunas 20-26 por 0s.

De:

12345678123456781234567812345678123456781234567812345678123456781234567812345678    

Para:

12345678123456781234000000345678123456781234567812345678123456781234567812345678

Isso seria para cada linha de um arquivo que poderia conter dezenas de milhares de linhas como essas.

Responder1

Não conheço nenhum especificamente, mas acabei de escrever um para você. Está escrito eminicialização automática. Você pode baixá-lo e compilá-lo sozinho usando o código abaixo ou pode baixar uma versão compiladaaqui. Se você quiser fazer alguma alteração, é só me avisar, verei o que posso fazer.

EDIT: se você precisar fazer isso também com um arquivo, me avise, posso fazer essa alteração.

EDIT # 2: Acabei de atualizá-lo para fazer arquivos (não sabia quais formatos você precisava, mas não tenho certeza de como será fácil fazer qualquer coisa além de arquivos de texto/log). Ele reportará qualquer linha que esteja fora do alcance. Também atualizei o link acima com a nova versão compilada.

#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiEdit.au3>
#include <File.au3>

Dim $s_Name = "FileStringReplacer"

Main()

Func Main()
    $h_Parent = GuiCreate($s_Name,400,340)
    GuiCtrlCreateLabel("File to Edit",5,5,90,20)
    $in_File = GuiCtrlCreateInput("",10,25,380,20,$ES_READONLY)
    $bt_Browse = GuiCtrlCreateButton("Find File",10,50,380,25)
    GuiCtrlCreateLabel("Request Status",5,80,90,20)
    $ed_Status = GuiCtrlCreateEdit("",10,100,380,100,$ES_READONLY + $WS_VSCROLL)
    GuiCtrlCreateLabel("Start Point",5,210,50,20)
    $in_Start = GuiCtrlCreateInput("",60,210,25,20)
    GuiCtrlCreateLabel("Stop Point",95,210,50,20)
    $in_Stop = GuiCtrlCreateInput("",150,210,25,20)
    GuiCtrlCreateLabel("Text to Insert",5,240,90,20)
    $in_String = GuiCtrlCreateInput("",10,260,380,20)
    $bt_Replace = GuiCtrlCreateButton("Replace",10,290,380,25)
    GuiSetState()
    Do
        $Msg = GUIGetMsg()

        If $Msg = $bt_Browse Then
            $h_File = FileOpenDialog("File to Modify",@MyDocumentsDir,"Text (*.txt;*.log)", 3)
            GuiCtrlSetData($in_File,$h_File)
        EndIf

        If $Msg = $bt_Replace Then
            GuiCtrlSetData($ed_Status,"")
            If GuiCtrlRead($in_File) <> "" Then
                If IsInt(Int(GuiCtrlRead($in_Start))) and IsInt(Int(GuiCtrlRead($in_Stop))) and Int(GuiCtrlRead($in_Start)) <> 0 and Int(GuiCtrlRead($in_Stop)) <> 0 Then
                    GuiCtrlSetState($bt_Browse,$GUI_DISABLE)
                    GuiCtrlSetState($bt_Replace,$GUI_DISABLE)
                    $h_File = FileOpen(GuiCtrlRead($in_File))
                    $i = 1
                    $s_Line = ""
                    While 1
                        $s_Line = FileReadLine($h_File,$i)
                        If @error Then
                            ExitLoop
                        EndIf
                        If StringLen($s_Line) > GuiCtrlRead($in_Stop) - GuiCtrlRead($in_Start) Then
                        $stringright = StringTrimLeft($s_Line,GuiCtrlRead($in_Stop))
                        $stringleft = StringLeft($s_Line,GuiCtrlRead($in_Start) -1 )
                        $newstring = $stringleft & GuiCtrlRead($in_String) & $stringright
                        _FileWriteToLine(GuiCtrlRead($in_File), $i, $newstring, 1)
                        Else
                            _GUICtrlEdit_AppendText(GuiCtrlGetHandle($ed_Status), @CRLF & "Edit to line " & $i & " failed, specified position is out of range")
                        EndIf
                        $i = $i + 1
                    WEnd
                    FileClose($h_File)
                    GuiCtrlSetState($bt_Browse,$GUI_ENABLE)
                    GuiCtrlSetState($bt_Replace,$GUI_ENABLE)
                Else
                    GuiCtrlSetData($ed_Status,"Error 102" & @CRLF & "Start and stop points must be numbers")
                EndIf
            Else
                GuiCtrlSetData($ed_Status,"Error 101" & @CRLF & "You must specify a file to edit")
            EndIf
        EndIf
        Until $Msg = $GUI_EVENT_CLOSE
    GUIDelete($h_Parent)
EndFunc

Responder2

Deve ser trivial em qualquer editor de texto. No gvim para a linha atual o comando pode ser020lc6l000000<esc>

Existe algum motivo especial para você querer evitar expressões regulares?


EDITAR

Aqui está uma instrução contendo uma expressão regular simples:s/^(.{19}).{6}/${1}000000/

Significa procurar

^      start at the beginning of a line
(      remember stuff found between parentheses
.      any single character
{19}   exactly 19 of them
)      end of the part we want to remember
.{6}   followed by any 6 characters which we won't remember

e substitua-os por

${1}   the first set of characters we remembered using () - 19 chars
000000 followed by six zeros (replacing the .{6} we ignore)

normalmente você escreveria ${1}como, $1mas quando for seguido por dígitos, você terá que usar {} para distinguir entre a décima parte lembrada $10 e a primeira parte $1 seguida por um literal 0.

Usado assim

perl -pie 's/^(.{19}).{6}/${1}000000/' foo.txt bar.txt any*.txt

para fazer a edição no local de todas as linhas em qualquer número de arquivos.Mas teste primeiro em uma cópia do arquivo!

Responder3

Responder4

Vimpode fazer isso com muita facilidade.

Abra o arquivo no Vim e digite:

:% normal 019l6r0<Enter>



:% normalsignifica executar os próximos comandos em cada linha do arquivo.

0significa: mova o cursor para o início da linha.

19lsignifica: mover o cursor para a direita 19 vezes

6r0significa: substitua os próximos 6 caracteres por 0


Eu sei que os comandos podem parecer um pouco enigmáticos no início. Mas você só precisa aprender alguns comandos muito simples para fazer o que precisa.

0move o cursor para o início da linha
$move o cursor para o final da linha

hmove o cursor para a esquerda
jmove o cursor para baixo
kmove o cursor para cima
lmove o cursor para a direita

rsubstitui o caractere sob o cursor pelo próximo caractere pressionado

Digite um número antes de qualquer comando para que esse comando seja executado "número" vezes.

:% normal <list of commands><Enter>faz uma lista de comandos em cada linha do arquivo


Você também pode gravar várias edições e reproduzi-las em cada linha do arquivo.

Grave comandos.

qa<commands>q

em seguida, reproduza os comandos em cada linha do arquivo.

:% normal @a<Enter>

informação relacionada