Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete specific line number(s) from a text file using sed?

I want to delete one or more specific line numbers from a file. How would I do this using sed?

like image 738
Justin Ethier Avatar asked Jan 21 '10 20:01

Justin Ethier


People also ask

How do you delete a specific line in a file using sed?

To delete a line, we'll use the sed “d” command. Note that you have to declare which line to delete. Otherwise, sed will delete all the lines.

How do I remove line numbers from a file in Linux?

The syntax is <address><command> ; where <address> can be either a single line like 5 or a range of lines like 5,10 , and the command d deletes the given line or lines. The addresses can also be regular expressions, or the dollar sign $ indicating the last line of the file.

How do I remove a number from sed?

How do I remove all digits or number from my text file or input using sed command? A. You need to use regular expression to remove digits or number from input. For example, 's/[0-9]*//g' will remove all numbers from the input.

How do I delete a specific line?

Delete lines or connectorsClick the line, connector, or shape that you want to delete, and then press Delete. Tip: If you want to delete multiple lines or connectors, select the first line, press and hold Ctrl while you select the other lines, and then press Delete.


7 Answers

If you want to delete lines from 5 through 10 and line 12th:

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

This will print the results to the screen. If you want to save the results to the same file:

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

This will store the unmodified file as file.bak, and delete the given lines.

Note: Line numbers start at 1. The first line of the file is 1, not 0.

like image 70
Brian Campbell Avatar answered Oct 03 '22 02:10

Brian Campbell


You can delete a particular single line with its line number by

sed -i '33d' file

This will delete the line on 33 line number and save the updated file.

like image 30
amit Avatar answered Oct 03 '22 02:10

amit


and awk as well

awk 'NR!~/^(5|10|25)$/' file
like image 44
ghostdog74 Avatar answered Oct 03 '22 02:10

ghostdog74


$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$ 
like image 23
Matthew Slattery Avatar answered Oct 03 '22 01:10

Matthew Slattery


This is very often a symptom of an antipattern. The tool which produced the line numbers may well be replaced with one which deletes the lines right away. For example;

grep -nh error logfile | cut -d: -f1 | deletelines logfile

(where deletelines is the utility you are imagining you need) is the same as

grep -v error logfile

Having said that, if you are in a situation where you genuinely need to perform this task, you can generate a simple sed script from the file of line numbers. Humorously (but perhaps slightly confusingly) you can do this with sed.

sed 's%$%d%' linenumbers

This accepts a file of line numbers, one per line, and produces, on standard output, the same line numbers with d appended after each. This is a valid sed script, which we can save to a file, or (on some platforms) pipe to another sed instance:

sed 's%$%d%' linenumbers | sed -f - logfile

On some platforms, sed -f does not understand the option argument - to mean standard input, so you have to redirect the script to a temporary file, and clean it up when you are done, or maybe replace the lone dash with /dev/stdin or /proc/$pid/fd/1 if your OS (or shell) has that.

As always, you can add -i before the -f option to have sed edit the target file in place, instead of producing the result on standard output. On *BSDish platforms (including OSX) you need to supply an explicit argument to -i as well; a common idiom is to supply an empty argument; -i ''.

like image 37
tripleee Avatar answered Oct 03 '22 03:10

tripleee


I would like to propose a generalization with awk.

When the file is made by blocks of a fixed size and the lines to delete are repeated for each block, awk can work fine in such a way

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

In this example the size for the block is 2000 and I want to print the lines [1..713] and [1026..1029].

  • NR is the variable used by awk to store the current line number.
  • % gives the remainder (or modulus) of the division of two integers;
  • nl=((NR-1)%BLOCKSIZE)+1 Here we write in the variable nl the line number inside the current block. (see below)
  • || and && are the logical operator OR and AND.
  • print $0 writes the full line

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

like image 27
Hastur Avatar answered Oct 03 '22 01:10

Hastur


The shortest, deleting the first line in sed

sed -i '1d' file

As Brian states here, <address><command> is used, <address> is <1> and <command> <d>.

like image 22
Timo Avatar answered Oct 03 '22 03:10

Timo