Відповіді:
З sed, як-от так:
sed '20,37d; 45d' < input.txt > output.txt
Якщо ви хотіли зробити це на місці:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU sed "робить це, створюючи тимчасовий файл і відправлення виводу в цей файл, а не до стандартного виводу. "... Я не знаю про будь-який інший" sed ", але логістика оновлення" на місці " редактором потоку не" обчислює ":)
Якщо файл зручно вписується в пам'ять, ви також можете використовувати його 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
Замініть wобряд на ,print, якщо ви хочете надрукувати результат, а не писати у файл. Якщо ви хочете зберегти оригінальний файл недоторканим і записати в інший файл, ви можете передати нове ім'я файлу в wпідкоманду обряду:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
Якщо ви не готові обчислити нові номери рядків після кожного dелементу, що є досить тривіальним для цього конкретного випадку (після видалення рядків 20-37, тобто 18 рядків, рядок 45 стає рядком 27), щоб ви могли запустити:
ed -s in_file <<IN
20,37d
27d
w
q
IN
Однак якщо вам доведеться видалити декілька чисел / діапазонів рядків, робота назад - це не мозок.
qкорисна команда наприкінці? Я здогадуюсь це виходить будь-яким способом.
Просто прочитайте його в пам'яті, змініть, а потім запишіть його назад. Можна зробити щось на кшталт
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
Деякі примітки:
Можна спочатку усікати файл, потім записувати в нього, а не писати, а потім усікати, як вище. Однак я не знаю прапор Python, який дозволяє читати, а потім робити усічений запис. Але, можливо, мені чогось не вистачає, оскільки документ не все так зрозуміло. Що приводить мене до
Іноді документи Python справді смоктають. Див. Http://docs.python.org/library/functions.html#open
Режими 'r +', 'w +' і 'a +' відкривають файл для оновлення (зауважте, що 'w +' обрізає файл).
Це щось означає для вас? Що за чорт "відкрите для оновлення"?
Я не знаю, чи краще це робити в python на відміну від чогось unixy, наприклад редактора потоків. Це може бути більш портативним, але я не знаю, наскільки портативний sed. Я просто написав це так, бо мені зручніше програмування на низькому рівні, ніж використання класичних інструментів Unix, які добре, якщо вони роблять саме те, що ви хочете, але (я думаю), як правило, менш гнучкі.
Цей підхід (маніпулювання файлом у пам'яті) торгує пам'яттю на диску. Він повинен працювати ОК на машинах з кількома Gb пам'яті для файлів до декількох сотень Мб. Python не обробляє рядки дуже ефективно, тому перехід на C / C ++, наприклад, трохи збільшить продуктивність і значно зменшить використання пам'яті.
Ви можете використовувати Vim в режимі Ex:
ex -sc '20,37d|45d|x' file
d видалити
x зберегти і закрити