Substituindo texto em arquivo em determinada largura

0

Como posso substituir em certas posições de coluna?

Exemplo: desejo substituir as colunas 20 a 26 por 0s.

De:

12345678123456781234567812345678123456781234567812345678123456781234567812345678    

Para:

12345678123456781234000000345678123456781234567812345678123456781234567812345678

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

    
por divided 27.10.2010 / 21:30

5 respostas

0

Eu não sei de um especificamente, mas eu acabei de escrever um para você. Está escrito em autoit . Você pode baixá-lo e compilá-lo usando o código abaixo, ou você pode baixar uma versão com problemas aqui . Se você quiser fazer alguma alteração, é só me avisar, vou ver o que posso fazer.

EDIT: se você precisa fazer isso com um arquivo também, me avise, eu posso fazer essa mudança.

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 nada além de arquivos de texto / log). Ele relatará qualquer linha que esteja fora do intervalo. Também atualizou 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
    
por 27.10.2010 / 23:28
1

Deve ser trivial em qualquer editor de texto. Em gvim para a linha atual, o comando pode ser 020lc6l000000<esc>

Existe algum motivo especial para evitar expressões regulares?

EDITAR

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

Significa pesquisar

^      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ê escreve ${1} as $1 mas quando é seguido por dígitos você tem 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 editar no local de todas as linhas em qualquer número de arquivos. Mas teste primeiro uma cópia do arquivo!

    
por 28.10.2010 / 00:10
0

Algo parecido com isto?

link

    
por 27.10.2010 / 21:38
0

Tente isto:

sed -i 's/^\(.\{19\}\).\{7\}/000000/' inputfile

ou

sed -ri 's/^(.{19}).{7}/000000/' inputfile
    
por 28.10.2010 / 08:56
0

Vim pode fazer isso com muita facilidade.

Abra o arquivo no Vim e digite:

:% normal 019l6r0<Enter>


:% normal significa fazer os próximos comandos em todas as linhas do arquivo.

0 significa: mova o cursor para o começo da linha.

19l significa: mova o cursor para a direita 19 vezes

6r0 significa: substitua os próximos 6 caracteres por 0

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

0 move o cursor para o começo da linha
$ move o cursor para o final da linha

h move o cursor para a esquerda
j move o cursor para baixo
k move o cursor para cima
l move o cursor para a direita

r substitui o caractere sob o cursor com o próximo caractere pressionado

Digite um número antes de qualquer comando para que o comando tenha o número "number".

:% 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 reproduzir as mesmas edições em todas as linhas do arquivo.

Comandos de registro.

qa<commands>q

então, repita os comandos em todas as linhas do arquivo.

:% normal @a<Enter>
    
por 29.10.2010 / 02:23