![Замена текста в файле определенной ширины](https://rvso.com/image/1254834/%D0%97%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0%20%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%B0%20%D0%B2%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B5%20%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9%20%D1%88%D0%B8%D1%80%D0%B8%D0%BD%D1%8B.png)
Как можно заменить в определенных позициях столбцов?
Пример: Я хочу заменить столбцы 20–26 нулями.
От:
12345678123456781234567812345678123456781234567812345678123456781234567812345678
К:
12345678123456781234000000345678123456781234567812345678123456781234567812345678
Это касается каждой строки в файле, который может содержать десятки тысяч таких строк.
решение1
Я не знаю конкретно одного, но я только что написал один для вас. Он написан наавтоит. Вы можете скачать и скомпилировать его самостоятельно, используя код ниже, или вы можете скачать скомпилированную версиюздесь. Если вы хотите внести какие-либо изменения, просто дайте мне знать, я посмотрю, что можно сделать.
EDIT: если вам нужно сделать это с файлом, дайте мне знать, я могу внести это изменение.
EDIT #2: Я только что обновил его для работы с файлами (не знал, какие форматы вам нужны, но не уверен, насколько легко будет работать с чем-либо, кроме текстовых/логовых файлов). Он сообщит о любой строке, которая находится вне диапазона. Также обновил ссылку выше с новой скомпилированной версией.
#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
решение2
Это должно быть тривиально в любом текстовом редакторе. В gvim для текущей строки команда может быть020lc6l000000<esc>
Есть ли какая-то особая причина, по которой вы хотите избегать регулярных выражений?
РЕДАКТИРОВАТЬ
Вот оператор, содержащий простое регулярное выражение:s/^(.{19}).{6}/${1}000000/
Это означает поиск
^ 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
и замените их на
${1} the first set of characters we remembered using () - 19 chars
000000 followed by six zeros (replacing the .{6} we ignore)
Обычно вы пишете ${1}
как $1
, но когда за ним следуют цифры, вам приходится использовать {}, чтобы отличить десятую запоминаемую часть $10 от первой части $1, за которой следует буквальный 0.
Используется так
perl -pie 's/^(.{19}).{6}/${1}000000/' foo.txt bar.txt any*.txt
для редактирования на месте всех строк в любом количестве файлов.Но сначала проверьте это на копии файла!
решение3
решение4
Вимможно сделать это очень легко.
Откройте файл в Vim, затем введите:
:% normal 019l6r0<Enter>
:% normal
означает выполнение следующих команд в каждой строке файла.
0
означает: переместить курсор в начало строки.
19l
означает: переместить курсор вправо 19 раз
6r0
означает: заменить следующие 6 символов на 0
Я знаю, что команды могут показаться немного загадочными на первый взгляд. Но вам нужно выучить всего несколько очень простых команд, чтобы сделать то, что вам нужно.
0
перемещает курсор в начало строки
$
перемещает курсор в конец строки
h
перемещает курсор влево
j
перемещает курсор вниз
k
перемещает курсор вверх
l
перемещает курсор вправо
r
заменяет символ под курсором на следующий нажатый символ
Введите число перед любой командой, чтобы она была выполнена указанное количество раз.
:% normal <list of commands><Enter>
выводит список команд на каждой строке файла
Вы также можете записать ряд правок, а затем воспроизвести те же правки в каждой строке файла.
Запись команд.
qa<commands>q
затем повторите команды в каждой строке файла.
:% normal @a<Enter>