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, $1
mas 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>
:% normal
significa executar os próximos comandos em cada linha do arquivo.
0
significa: mova o cursor para o início da linha.
19l
significa: mover 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 início. Mas você só precisa aprender alguns comandos muito simples para fazer o que precisa.
0
move o cursor para o início 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 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>