![以特定寬度替換文件中的文本](https://rvso.com/image/1254834/%E4%BB%A5%E7%89%B9%E5%AE%9A%E5%AF%AC%E5%BA%A6%E6%9B%BF%E6%8F%9B%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%96%87%E6%9C%AC.png)
如何在某些列位置替換 at ?
範例:我想用 0 取代第 20-26 列。
從:
12345678123456781234567812345678123456781234567812345678123456781234567812345678
到:
12345678123456781234000000345678123456781234567812345678123456781234567812345678
這適用於文件中的每一行,該文件可能包含數萬行這樣的行。
答案1
我不知道具體是什麼,但我只是為你寫了一篇。它寫在自動。您可以使用下面的程式碼自行下載並編譯,也可以下載編譯版本這裡。如果您想要進行任何更改,請告訴我,我會看看我能做些什麼。
編輯:如果您還需要對文件執行此操作,請告訴我,我可以進行更改。
編輯#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
用按下的下一個字元替換遊標下的字符
在任何命令之前鍵入數字可以使該命令執行“number”次。
:% normal <list of commands><Enter>
在文件中的每一行上執行命令列表
您也可以記錄一堆編輯,然後在文件的每一行上重播相同的編輯。
記錄命令。
qa<commands>q
然後,在檔案的每一行重播指令。
:% normal @a<Enter>