網站首頁 編程語言 正文
1、前言
有這樣一個需求,我們查找到文件中帶有某個關鍵詞的一行內容后,對該行內容進行替換,替換成我們需要的新內容,比如修改網絡配置文件、修改圖片地址、修改代碼中所有關鍵詞等,類似于編輯器中的關鍵詞替換功能,只不過我們是直接判斷文件而已。
2、實現覆蓋某一行文件內容的思路
1、打開文件
2、讀取文件每一行
3、根據關鍵詞判斷是否是需要覆蓋的行,是的話則從行開頭寫內容,使其覆蓋該行舊內容
由于是覆蓋,所以我們有一個前提是新寫入的內容長度需要大于等于舊內容的長度,至于新內容小于舊內容的情況下,我們在擴展中再做嘗試,基本思路包括兩個:1、寫入空內容覆蓋多出的位置(應該不行,可以試一下);2、新內容寫入后直接加入換行,然后將之前文件剩余內容覆蓋多出來的這部分,還是覆蓋的思想。
3、實現覆蓋某一行內容的代碼示例
我們這里以修改我的虛擬機中的網絡配置文件為例做一個簡單的示例(記得先備份):
原本的Ubuntu配置文件內容:
$ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto ens33
iface ens33 inet static
address 40.40.40.210
gateway 40.40.40.1
netmask 255.255.255.0
然后我們通過address、gateway、netmask等關鍵詞來修改最后三行的內容,以此來修改配置文件中的ip地址、網關和子網掩碼。
代碼內容:
package main import ( ?? ?"bufio" ?? ?"fmt" ?? ?"io" ?? ?"os" ?? ?"strings" ) func main() { ? ? //讀寫方式打開文件 ?? ?file, err := os.OpenFile("/etc/network/interfaces", os.O_RDWR, 0666) ?? ?if err != nil { ?? ??? ?fmt.Println("open file filed.", err) ?? ??? ?return ?? ?} ? ? //defer關閉文件 ?? ?defer file.Close() ? ? //獲取文件大小 ?? ?stat, err := file.Stat() ?? ?if err != nil { ?? ??? ?panic(err) ?? ?} ?? ?var size = stat.Size() ?? ?fmt.Println("file size:", size) ? ? //讀取文件內容到io中 ?? ?reader := bufio.NewReader(file) ?? ?pos := int64(0) ?? ?ip := "40.40.40.220" ?? ?gateway := "40.40.40.1" ?? ?netmask := "255.255.255.0" ?? ?for { ? ? ? ? //讀取每一行內容 ?? ??? ?line, err := reader.ReadString('\n') ?? ??? ?if err != nil { ? ? ? ? ? ? //讀到末尾 ?? ??? ??? ?if err == io.EOF { ?? ??? ??? ??? ?fmt.Println("File read ok!") ?? ??? ??? ??? ?break ?? ??? ??? ?} else { ?? ??? ??? ??? ?fmt.Println("Read file error!", err) ?? ??? ??? ??? ?return ?? ??? ??? ?} ?? ??? ?} ?? ??? ?fmt.Println(line) ? ? ? ? //根據關鍵詞覆蓋當前行 ?? ??? ?if strings.Contains(line, "address") { ?? ??? ??? ?bytes := []byte("address " + ip + "\n") ?? ??? ??? ?file.WriteAt(bytes, pos) ?? ??? ?} else if strings.Contains(line, "gateway") { ?? ??? ??? ?bytes := []byte("gateway " + gateway + "\n") ?? ??? ??? ?file.WriteAt(bytes, pos) ?? ??? ?} else if strings.Contains(line, "netmask") { ?? ??? ??? ?bytes := []byte("netmask " + netmask + "\n") ?? ??? ??? ?file.WriteAt(bytes, pos) ?? ??? ?} ? ? ? ? //每一行讀取完后記錄位置 ?? ??? ?pos += int64(len(line)) ?? ?} }
結果:
$ sudo ./go_build_test_go_linux?
[sudo] xx 的密碼:?
file size: 180
# interfaces(5) file used by ifup(8) and ifdown(8)auto lo
iface lo inet loopback
auto ens33
iface ens33 inet static
address 40.40.40.210
gateway 40.40.40.1
netmask 255.255.255.0
File read ok!
$ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopbackauto ens33
iface ens33 inet static
address 40.40.40.220
gateway 40.40.40.1
netmask 255.255.255.0
關鍵點:每讀取一行記錄目前的移動位置,然后調用file.WriteAt進行內容覆蓋寫入(不能是追加方式),因為找到這一行的時候記錄的位置正好是上一行的末尾,所以正好覆蓋。
4、擴展
其實最方便的方式其實是shell腳本的方式,然后通過各種語言都可以調用,并且某些時候也可以單獨執行腳本。
其次,對于新內容長度少于舊內容的長度時無法做到全部覆蓋,這個時候就稍微麻煩一點,再下下一行的時候或者其余的內容全部讀取然后覆蓋寫入即可。
不明白接口使用的查看一下官方的io包,后面我們也會再專注整理一下io標準庫的接口。
原文鏈接:https://blog.csdn.net/weixin_39510813/article/details/115675198
相關推薦
- 2022-12-16 Python海象運算符代碼分析及知識點總結_python
- 2022-10-27 使用python+pandas讀寫xlsx格式中的數據_python
- 2022-09-03 .NET使用System.Timers.Timer類實現程序定時執行_實用技巧
- 2022-11-06 MobLink?Android端業務場景簡單說明_Android
- 2023-06-16 GO的鎖和原子操作的示例詳解_Golang
- 2022-10-16 Pytorch?linear?多維輸入的參數問題_python
- 2022-12-08 C++?float轉std::string?小數位數控制問題_C 語言
- 2022-05-27 Jmeter如何使用BeanShell取樣器調用Python腳本_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支