Удалить конкретный номер(ы) строки из текстового файла с помощью sed?
Я хочу удалить один или несколько конкретных номеров строк из файла. Как бы я это сделал, используя sed?
6 ответов
Если вы хотите удалить строки с 5 по 10 и 12:
sed -e '5,10d;12d' file
выводит результаты на экран. Если вы хотите сохранить результаты в тот же файл:
sed -i.bak -e '5,10d;12d' file
этот файл обратно до file.bak
и удалите заданные строки.
вы можете удалить одну строку с ее номером строки sed-i '33d' file
это удалит строку на 33 номер строки и сохранить обновленный файл.
это очень часто симптом антиобразец. Инструмент, который произвел номера строк, вполне может быть заменен тем, который удаляет строки сразу. Например:
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(где deletelines
это утилита, которую вы себе представляете, вам нужно) то же самое, что и
grep -v error logfile
сказав, что, если вы находитесь в ситуации, когда вам действительно нужно, чтобы выполнить эту задачу, вы можете создать простой sed
скрипт из файла номеров строк. С юмором (но возможно, немного смущенно) вы можете сделать это с sed
.
sed 's%$%d%' linenumbers
это принимает файл номеров строк, по одному на строку, и производит на стандартном выходе те же номера строк с d
добавляются после каждого. Это действительно sed
скрипт, который мы можем сохранить в файл, или (на некоторых платформах) трубу в другой sed
например:
sed 's%$%d%' linenumbers | sed -f - logfile
на некоторых платформах, sed -f
не понимает аргумент option -
означает стандартный ввод, так что у вас есть чтобы перенаправить скрипт во временный файл и очистить его, когда вы закончите, или, возможно, заменить одинокую черточку на /dev/stdin
или /proc/$pid/fd/1
если ваша ОС (или оболочка) имеет это.
как всегда, вы можете добавить -i
до иметь sed
отредактируйте целевой файл на месте, вместо получения результата на стандартном выходе. На платформах * BSDish (включая OSX) вам нужно предоставить явный аргумент -i
также; распространенная идиома-предоставить пустой аргумент; -i ''
.
Я хотел бы предложить обобщение с awk.
когда файл сделан блоками фиксированного размера и строки для удаления повторяются для каждого блока, awk может отлично работать таким образом
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print }'
OriginFile.dat > MyOutputCuttedFile.dat
в этом примере размер блока составляет 2000, и я хочу напечатать строки [1..713] и [1026..1029].
-
NR
- переменная, используемая awk для хранения текущего номера строки. -
%
дает остаток (или модуль) деления двух целых чисел; -
nl=((NR-1)%BLOCKSIZE)+1
здесь мы пишем в переменной nl номер строки внутри текущего блока. (см. ниже) -
||
и&&
- это логический оператор или и и. -
print
пишет полную строку
Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
+1 We add again 1 because we want to restore the desired order.
+-----+------+----------+------------+
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 3 | 0 | 2 | 3 |
| 4 | 1 | 0 | 1 |
+-----+------+----------+------------+