2016-04-16 107 views
-1

我想用一個新的生產線,以取代在一個文件中的一行,例如是:替換文本文件符合新行

文件:

test 
test 
test 
testing 
test 

來源:

def remove_line(line) 
    if line == line 
    #remove line including whitespace 
    File.open('test.txt', 'a+') { |s| s.puts('removed successfully') } 
    end 
end 

所以這個預期的輸出會是這樣的:

remove_line('testing') 
test 
test 
test 
removed successfully 
test 

現在我已經做了一些研究,只能找到添加一個空白行,我想我可以通過它,並刪除所有空行,只是追加到文件,但必須有一個更簡單的方法來取代一條線與另一個字符串?

+0

當你說'if line == line'你想做什麼?這總是會是事實。 – Nobita

+0

@Nobita我認爲他是指它作爲例子,如果作爲參數給出的字符串等於文件中的行之一,重寫行等。 – 13aal

回答

1

首先,打開文件並保存實際內容。然後,替換字符串並將完整內容寫回文件。

def remove_line(string) 
    # save the content of the file 
    file = File.read('test.txt') 
    # replace (globally) the search string with the new string 
    new_content = file.gsub(string, 'removed succesfully') 
    # open the file again and write the new content to it 
    File.open('test.txt', 'w') { |line| line.puts new_content } 
end 

或者,代替全局替換:

def remove_line(string) 
    file = File.read('test.txt') 
    new_content = file.split("\n") 
    new_content = new_content.map { |word| word == string ? 'removed succesfully' : word }.join("\n") 
    File.open('test.txt', 'w') { |line| line.puts new_content } 
end 
+0

這覆蓋整個文件 – JasonBorne

+0

它寫入文件到你需要什麼。你可以嘗試使用'File.seek',它不會重寫整個文件,但是你需要用完全相同大小的另一個字符串替換字符串。 – user3097405

+0

編輯第二種方法,因爲我已經離開聲明全局替換字符串。 – user3097405

0

我找到了一個參考答案here它不完全一樣,因爲他們正在尋找一個模式。

因此,這裏是我怎麼會去這樣做:

def remove_line(line) 
    file.open('test.txt', 'a+').each_line do |line| 
    line.gsub('<line/to/replace>', '<new/line/here>') 
    end 
end 

這應該更換給出你想要的任何新行的說法,行其替換爲..

+0

這是行不通的。 – JasonBorne

0

鑑於這種輸入文件,存儲爲 「test.txt的」:

test 
test 
test 
testing 
test 

和此示例代碼:

def remove_line(line_to_remove) 
    File.foreach("test.txt").with_index do |line, line_num| 
    line.gsub!(/[\r\n]+$/, '') 
    if line == line_to_remove 
     puts "removed successfully" 
    else 
     puts line 
    end 
    end 
end 

您可以成功運行:

remove_line('testing') 

,並得到如下的輸出:

test 
test 
test 
removed successfully 
test 

函數採用行刪除的內容,並打開文件「行由行」的時尚。這是慣用的Ruby,並且應該優於「混淆」文件,正如在SO question的接受答案中所解釋的那樣。

一旦我們有了一條線,就有必要去掉它的線尾。由於我們不知道將要運行哪個平臺(或創建文本文件),因此我們使用正則表達式來查找所有已知行結束字符('\ r \ n'是Windows'\ n'是Linux/Unix/Mac OS X,'\ r'是Mac Classic)。

然後我們檢查一下該行是否與我們想要刪除的行相匹配。如果匹配,我們從輸出中省略它,而是打印它已被「成功移除」;否則,我們輸出不匹配的行。

這符合原始設計意圖,但是,有很多事情要做,以改善設計,並使整體更有用的功能。那麼,爲什麼不繼續做呢?

首先,我們將使函數以文件名作爲參數。這將從foreach呼叫中移除硬編碼的"test.txt"文件名。這將使這種變化發生了:

def remove_line(filename, line_to_remove) 
    File.foreach(filename).with_index do |line, line_num| 
    line.gsub!(/[\r\n]+$/, '') 
    if line == line_to_remove 
     puts "removed successfully" 
    else 
     puts line 
    end 
    end 
end 

可以成功運行這種方式,它會產生完全相同的輸出:

remove_line("test.txt", "testing") 

接下來,讓我們改變輸出是如何發生的,以及我們」我會用塊來做到這一點,因爲那是Ruby的方式。這裏的功能是什麼樣子與塊輸出:

def remove_line(filename, line_to_remove, &block) 
    proc = block_given? ? block : lambda {|s| puts s } 
    File.foreach(filename).with_index do |line, line_num| 
    line.gsub!(/[\r\n]+$/, '') 
    if line == line_to_remove 
     proc.call "removed successfully" 
    else 
     proc.call line 
    end 
    end 
end 

這是建立與可選塊參數,所以你可以把它完全像以前的版本,使其工作完全相同的方式,也可以用一個明確的塊來調用它並做一些很酷的事情。

remove_line("test.txt", "testing") {|s| puts "#{s} in your pants" } 

而且具有童心的額外的緊要關頭,你會得到這樣的輸出:此運行它修改字符串調用puts稍前打印行的例子

test in your pants 
test in your pants 
test in your pants 
removed successfully in your pants 
test in your pants 

您現在有權力做有趣的事情,從其他有趣的事情建立起來。明智地使用它,並繼續這樣做Ruby的方式。