Как удалить определенные строки (используя номера строк) в файле?

27

Есть определенные строки, которые я хочу удалить из файла. Допустим, это строка 20-37, а затем строка 45. Как бы я это сделал, не указав содержание этих строк?

tshepang
источник
Насколько большой ваш файл? Может ли он быть загружен в память?
Фахим Митха
Несколько килобайт
tshepang

Ответы:

29

С sed, вот так:

sed '20,37d; 45d' < input.txt > output.txt

Если вы хотите сделать это на месте:

sed --in-place '20,37d; 45d' file.txt
п.д.о.
источник
Есть ли способ сделать это на месте?
tshepang
Я предлагаю файл sed -i
enzotib
1
@Tshepang: Используйте ed, или GNU sed -i, или sponge, или метод большого файла .
Жиль "ТАК - перестань быть злым"
3
Я часто задавался вопросом о возможном вводящем в заблуждение термине « место» , когда ссылался на «sed», поэтому я искал его в «man sed»: --in-place [= SUFFIX] This option specifies that files are to be edited in-place. GNU sed 'делает это, создавая временный файл и отправлять вывод в этот файл, а не в стандартный вывод. ... Я не знаю ни о каком другом «sed», но логика обновления «на месте» с помощью потокового редактора не «вычисляет» :)
Peter.O
2
По моему опыту, большинство методов на месте используют временный файл.
Фахим Митха
5

Если файл удобно помещается в памяти, вы также можете использовать ed.
Команды очень похожи на приведенную sedвыше, но с одним заметным отличием : вы должны передать список номеров строк / диапазонов, которые должны быть удалены, в порядке убывания (от самой высокой строки / диапазона до самой низкой). Причина в том, что когда вы удаляете / вставляете / разделяете / соединяете строки с ed, текстовый буфер обновляется после каждой подкоманды, поэтому, если вы удаляете некоторые строки, остальные следующие строки больше не будут находиться в той же позиции в буфере, следующая подкоманда выполнена. Таким образом, вы должны начать назад 1 . Редактирование на
месте :

ed -s in_file <<IN
45d
20,37d
w
q
IN

или

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

или

printf '%s\n' 45d 20,37d w q | ed -s in_file

Замените write на ,print, если вы хотите напечатать полученный результат вместо записи в файл. Если вы хотите сохранить исходный файл без изменений и записать в другой файл, вы можете передать новое имя файла wподкоманде rite:

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1 Если вы не хотите рассчитывать новые номера строк после каждого dэлемента elete, что довольно тривиально для этого конкретного случая (после удаления строк 20-37, т.е. 18 строк, строка 45 становится строкой 27), чтобы вы могли выполнить:

ed -s in_file <<IN
20,37d
27d
w
q
IN

Однако, если вам нужно удалить несколько номеров строк / диапазонов, работать в обратном направлении не составит труда.

don_crissti
источник
qПолезна ли команда в конце? Я предполагаю, что это выходит так или иначе.
Том Фенек,
@TomFenech - не все реализации завершаются так или иначе (хотя большинство так и делают ... Я больше не могу найти
ветку,
1

Просто прочитайте это в память, измените это, затем запишите это назад. Вы можете сделать что-то вроде

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

Протестировано с 5-строчным файлом. Кредиты http://pleac.sourceforge.net/pleac_python/fileaccess.html см. В разделе «Изменение файла на месте без временного файла». Смотрите также /programming/125703/how-do-i-modify-a-text-file-in-python

Некоторые заметки:

  1. Можно сначала обрезать файл, затем записать в него, а не писать, а затем обрезать, как указано выше. Однако я не знаю флага Python, который позволяет читать, а затем выполнять усеченную запись. Но, может быть, я что-то упустил, так как документ не совсем ясен. Что подводит меня к

  2. Иногда документы Python действительно отстой. См. Http://docs.python.org/library/functions.html#open.

    Режимы «r +», «w +» и «a +» открывают файл для обновления (обратите внимание, что «w +» усекает файл).

    Это что-то значит для тебя? Что, черт возьми, «открыто для обновления»?

  3. Я не знаю, лучше ли делать это в python, в отличие от чего-то юниксного, такого как потоковый редактор. Это может быть более портативным, но я не знаю, как портативный SED. Я просто написал это так, потому что мне удобнее программировать на низком уровне, чем использовать классические инструменты Unix, которые хороши, если они делают именно то, что вы хотите, но (я думаю), как правило, менее гибкие.

  4. Этот подход (манипулирование файлом в памяти) меняет память на дисковое пространство. Он должен нормально работать на машинах с несколькими ГБ памяти для файлов размером до нескольких сотен МБ. Python не очень эффективно обрабатывает строки, поэтому, например, переход на C / C ++ немного повысит производительность и значительно сократит использование памяти.

Фахим Митха
источник
0

Вы можете использовать Vim в режиме Ex:

ex -sc '20,37d|45d|x' file
  1. d удалять

  2. x сохранить и закрыть

Стивен Пенни
источник