2014-11-04 47 views
1

我有一個〜700,000行的文件,我想用bash腳本或其他方法刪除一堆特定行(〜30,000)。如何從文件中刪除大量行

我知道我可以用SED刪除線:

sed -i.bak -e '1d;34d;45d;678d' myfile.txt # an example 

我有一個文本文件中的行,但我不知道如果我可以用它輸入到sed的,也許perl的?

感謝

+1

文本文件的格式是什麼?按摩數據,使其看起來像一個sed表達式......儘管有30,000個值,但您可能會碰到sed參數大小的限制。 – 2014-11-04 02:04:46

+0

您的文件是排序的,還是可以排序? – 2014-11-04 02:04:51

+0

看看這個帖子,它是非常相似的... http://stackoverflow.com/questions/26670650/selecting-a-large-number-of-specific-rows-in-file/26672005#26672005 – 2014-11-04 09:34:39

回答

2

有幾個選項:

sed <(sed 's/$/d/' lines_file) data_file 
awk 'NR==FNR {del[$1]; next} !(FNR in del)' lines_file data_file 
perl -MPath::Class -e ' 
    %del = map {$_ => 1} file("lines_file")->slurp(chomp => 1); 
    $f = file("data_file")->openr(); 
    while (<$f>) { 
    print unless $del{$.}; 
    } 
' 
+0

謝謝你的所有答案但我喜歡不同的選擇! – user2380782 2014-11-04 16:47:16

0

如果你可以創建格式

1d 
34d 
45d 
678d 

的一個文本文件,然後就可以像

sed -i.bak -f scriptfile datafile 
1

運行的東西可以使刪除使用SED文件中的行。 首先製作要刪除的行的列表。 (一行一行代碼)

$ cat lines 
1 
34 
45 
678 

將此文件轉換爲sed格式。

$ sed -e 's|$| d|' lines >lines.sed 
$ cat lines.sed 
1 d 
34 d 
45 d 
678 d 

現在使用這個sed的文件,並給它輸入到sed命令。

$ sed -i.bak -f lines.sed file_with_70k_lines 

這將刪除線條。

2
perl -ne' 
    BEGIN{ local @ARGV =pop; @h{<>} =() } 
    exists $h{"$.\n"} or print; 
' myfile.txt lines 
0

您可以使用一個真正的編輯器,ed是標準的編輯器。

我假設你的線是在一個文件中lines.txt,每行一個數,例如,

1 
34 
45 
678 

然後(具有明顯的bashism):

ed -s file.txt < <(sed -n '/^[[:digit:]]\+$/p' lines.txt | sort -nr | sed 's/$/d/'; printf '%s\n' w q) 

第一sed僅選擇來自文件lines.txt的數字(以防萬一)。

這裏有一些很特別的事情要考慮:當刪除第1行時,原始文件中的第34行變爲第33行。因此,最好從結尾刪除行:從678開始,然後是45,這就是爲什麼我們使用sort -nr(以相反順序對數字進行排序)。最後的sedded的刪除命令)附加到數字中。

然後我們發出w(寫)和q(退出)命令。

請注意,這將覆蓋原始文件!