Удалить конкретные номера строк из текстового файла, используя sed?

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

8 ответов

Решение

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

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

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

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

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

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

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

И как хорошо

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 не понимает аргумент опции - что означает стандартный ввод, поэтому вам нужно перенаправить скрипт во временный файл и очистить его, когда вы закончите, или, возможно, заменить одинокий штрих на /dev/stdin или же /proc/$pid/fd/1 если ваша ОС (или оболочка) имеет это.

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

Самый короткий, удалив первую строку в sed

sed -i '1d' file

Как заявляет здесь Брайан , <address><command> используется, <address> является <1> а также <command> <d>.

Я хотел бы предложить обобщение с помощью 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 номер строки внутри текущего блока. (увидеть ниже)
  • || а также && являются логическим оператором OR и AND.
  • 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      |
+-----+------+----------+------------+

cat -b /etc/passwd | sed -E 's/^( )+(<line_number>)(\t)(.*)/--removed---/g;s/^( )+([0-9]+)(\t)//g'

cat -b-> печатать строки с числами

s/^( )+(<line_number>)(\t)(.*)//g-> заменить номер строки на нуль (удалить строку)

s/^( )+([0-9]+)(\t)//g#удалить номера catпечатный

Другие вопросы по тегам