2014-11-04 3 views
1

У меня есть файл с ~ 700 000 строк, и я хотел бы удалить кучу определенных строк (~ 30 000) с использованием сценариев bash или другого метода.Как удалить большое количество строк из файла

Я знаю, что могу удалить строки с помощью СЭД:

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

У меня есть строки в текстовом файле, но я не знаю, могу ли я использовать его в качестве входных данных СЭД, может быть, Perl ??

Благодаря

+1

Каков формат текстового файла? Массаж данных, чтобы он выглядел как выражение sed ... хотя с 30 000 значений вы можете столкнуться с ограничением размера аргумента sed. –

+0

Отсортированы ли ваши файлы или их можно отсортировать? –

+0

Посмотрите на это сообщение, это очень похоже ... http://stackoverflow.com/questions/26670650/selecting-a-large-number-of-specific-rows-in-file/26672005#26672005 –

ответ

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

0

Если вы можете создать текстовый файл формата

1d 
34d 
45d 
678d 

, то вы можете запустить что-то вроде

sed -i.bak -f scriptfile datafile 
1

Вы можете сделать удалить строки, используя патч в файл. Сначала создайте список линий для удаления. (Номер одной строки для одной строки)

$ 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 (для сортировки чисел в обратном порядке). Финал sed добавляет d (ed) к номерам.

Затем мы выдаем команды w (написать) и q (quit).

Обратите внимание, что это перезаписывает исходный файл!

Смежные вопросы