Замена текста в файле определенной ширины

Замена текста в файле определенной ширины

Как можно заменить в определенных позициях столбцов?

Пример: Я хочу заменить столбцы 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>

Связанный контент