How can I delete a specific lines from a file based on line numbers that are contained in another file? I know how to delete specific lines by just providing them on the command line, but I do not know how to delete specific lines based on lines numbers that are contained in another file. The file containing the line numbers is in the following format:
15768
15775
15777
15782
15784
15789
15791
15798
15800
15807
15809
15815
15817
15824
15826
There are 2073 lines total that I need to remove. I've tried searching around for how to do this although I was not able to an example similar to this.
Thanks for your help.
Assuming the line numbers to be deleted are in a file to-be-deleted
and the data is in big-data-file
, then, using Bash process substitution:
sed -f <(sed 's/$/d/' to-be-deleted) big-data-file > smaller-data-file
The inner sed 's/$/d'
command converts the line numbers into sed
delete operations. The outer sed
commands reads the delete commands and applies the operations to the big data file.
Using awk:
awk 'FNR==NR{a[$0];next} !(FNR in a)' f1 f2
ed
is the standard editor.
Here's a possibility to drive ed
to do your edit (in place):
#!/bin/bash
ed -s file < <(
while read line; do
[[ $line =~ ^[[:digit:]]+$ ]] || continue
printf "%d d\n" "$line"
done < lines
echo "wq"
)
this will open the file file
with ed
, read the file lines
that contains the line numbers, check that each read line is indeed a number, then give to ed
the command to delete that number, and when all is done ask ed
to write and quit wq
.
You might want to replace the [[ $line =~ ^[[:digit:]]+$ ]] || continue
line by:
[[ $line =~ ^[[:digit:]]+$ ]] || { printf >&2 "*** WARNING: Line %d not deleted\n" "$line"; continue; }
so as to be warned when invalid lines are present in the file lines
.
Make sure you read glenn jackmann's comment:
I've heard some older implementations of ed
do not accept wq
as a single command: printf "%s\n" w q
YMMV.