2016-02-13 61 views
2

在Go中可以跳轉到文件中的特定行號並刪除它?像Python中的linecache跳轉到文件中的特定行中去

我想匹配文件中的一些子字符串並刪除相應的行。匹配部分我已經照顧,我有一個數組,我需要刪除行號,但我堅持如何刪除文件中的匹配行。

+1

沒有辦法直接跳到沒有迭代的一行。雖然可以通過Seek()和ReadAt()來跳轉到一個偏移量(字節長度)。爲什麼不逐行讀取輸入文件並將這些行寫入新文件,而忽略與您的子字符串匹配的行呢? – Nadh

回答

0

我寫了一個小函數,允許您從文件中刪除特定行。

package main 

import (
    "io/ioutil" 
    "os" 
    "strings" 
) 

func main() { 
    path := "path/to/file.txt" 
    removeLine(path, 2) 
} 

func removeLine(path string, lineNumber int) { 
    file, err := ioutil.ReadFile(path) 
    if err != nil { 
     panic(err) 
    } 

    info, _ := os.Stat(path) 
    mode := info.Mode() 

    array := strings.Split(string(file), "\n") 
    array = append(array[:lineNumber], array[lineNumber+1:]...) 
    ioutil.WriteFile(path, []byte(strings.Join(array, "\n")), mode) 
} 
0

基於我讀取的linecache模塊,它將一個文件並基於'\ n'行結尾將其分解爲一個數組。您可以使用stringsbytes在Go中複製相同的行爲。您也可以使用bufio庫逐行讀取文件,並僅存儲或保存所需的行。

package main 

import (
    "bytes" 
    "fmt" 
) 
import "io/ioutil" 

func main() { 

    b, e := ioutil.ReadFile("filename.txt") 
    if e != nil { 
     panic(e) 
    } 
    array := bytes.Split(b, []byte("\n")) 

    fmt.Printf("%v", array) 
} 
+0

我修復了您的代碼以便編譯。 – peterSO

+0

謝謝。 Textarea的不是我的首選IDE :)。 – Sean

+0

我使用了Go Playground:http://play.golang.org/ – peterSO

0

這是一個老問題,但如果有人正在尋找一個解決方案,我寫了一個包處理去文件中的任何行。 Link here。它可以打開一個文件並尋找到任何行位置,而無需將整個文件讀入內存和分割。

import "github.com/stoicperlman/fls" 

// This is just a wrapper around os.OpenFile. Alternatively 
// you could open from os.File and use fls.LineFile(file) to get f 
f, err := fls.OpenFile("test.log", os.O_CREATE|os.O_WRONLY, 0600) 
defer f.Close() 

// return begining line 1/begining of file 
// equivalent to f.Seek(0, io.SeekStart) 
pos, err := f.SeekLine(0, io.SeekStart) 

// return begining line 2 
pos, err := f.SeekLine(1, io.SeekStart) 

// return begining of last line 
pos, err := f.SeekLine(0, io.SeekEnd) 

// return begining of second to last line 
pos, err := f.SeekLine(-1, io.SeekEnd) 

不幸的是,我不知道如何刪除,這只是處理讓你到文件中的正確位置。對於你的情況,你可以用它來到你想要刪除的行並保存位置。然後找到下一行並保存。您現在可以刪除該行的書擋。

// might want lineToDelete - 1 
// this acts like 0 based array 
pos1, err := f.SeekLine(lineToDelete, io.SeekStart) 

// skip ahead 1 line 
pos2, err := f.SeekLine(1, io.SeekCurrent) 

// pos2 will be the position of the first character in next line 
// might want pos2 - 1 depending on how the function works 
DeleteBytesFromFileFunction(f, pos1, pos2)