Удалить определенный номер (ы) строки из текстового файла с помощью sed?

StackOverflow https://stackoverflow.com/questions/2112469

  •  22-09-2019
  •  | 
  •  

Вопрос

Я хочу удалить один или несколько конкретных номеров строк из файла.Как бы я сделал это, используя sed?

Это было полезно?

Решение

Если вы хотите удалить строки с 5 по 10 и 12:

sed -e '5,10d;12d' file

Это выведет результаты на экран.Если вы хотите сохранить результаты в тот же файл:

sed -i.bak -e '5,10d;12d' file

Это приведет к созданию резервной копии файла в file.bak, и удалите указанные строки.

Примечание:Номера строк начинаются с 1.Первая строка файла равна 1, а не 0.

Другие советы

Вы можете удалить конкретную отдельную строку с ее номером строки с помощью файл sed - i '33d'

Это приведет к удалению строки с номером строки 33 и сохранению обновленного файла.

и awk также

awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$ 

Это очень часто является симптомом антипаттерна.Инструмент, который создавал номера строк, вполне может быть заменен инструментом, который сразу удаляет строки.Например;

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 перед тем, как -f возможность иметь sed отредактируйте целевой файл на месте, вместо того чтобы выдавать результат на стандартном выводе.На платформах *BSDish (включая OSX) вам необходимо указать явный аргумент для -i также;распространенной идиомой является предоставление пустого аргумента; -i ''.

Я хотел бы предложить обобщение с помощью awk.

Когда файл состоит из блоков фиксированного размера и строки для удаления повторяются для каждого блока, awk может работать нормально таким образом

awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print  $0}'
 OriginFile.dat > MyOutputCuttedFile.dat

В этом примере размер блока равен 2000, и я хочу напечатать строки [1..713] и [1026..1029].

  • NR это переменная, используемая awk для хранения текущего номера строки.
  • % дает остаток (или модуль) от деления двух целых чисел;
  • nl=((NR-1)%BLOCKSIZE)+1 Здесь мы записываем в переменную NL номер строки внутри текущего блока.(смотрите ниже)
  • || и && являются логическим оператором или и И.
  • print $0 записывает полную строку

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      |
+-----+------+----------+------------+

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top