Reputation: 446
I have two files.
file.txt
and delete.txt
file.txt
contains the following for ex.:
/somedirectory/
/somedirectory2/somefile.txt
/anotherfile.txt
delete.txt
contains:
/somedirectory/
/somedirectory2/somefile.txt
I need to delete the rows from file.txt
that are contained within delete.txt
cat file.txt
should result with:
/anotherfile.txt
So far I've tried this with no luck:
while read p; do
line=$p;
sed -i '/${line}/d' file.txt;
done < delete.txt
I don't receive any error, it just doesn't edit my file.txt
file. I've tested the while loop with an echo ${line}
and it works as expected in that scenario.
Any suggestions?
Note: the while loop above doesn't work as expected even when I took the forward slashes off of the files.
Upvotes: 4
Views: 814
Reputation: 2969
Use comm
instead:
comm -23 file.txt delete.txt
The input files must be sorted, though. If they are not:
comm -23 <(sort file.txt) <(sort delete.txt)
Upvotes: 1
Reputation: 2091
With a simple grep
:
grep -vFxf delete.txt file.txt > temp.txt && mv temp.txt file.txt
Upvotes: 5
Reputation: 79
The ${line} inside the single quotes will not get expanded, so it would be looking for the actual string ${line} in file.txt. Put that into your sample file to see if it gets removed.
However, you'll still have problems because the slashes inside delete text will get interpreted by sed, so the regular expression won't get properly delimited. You'd have to jump through some hoops to get every character in your input line properly quoted as literal in order to use sed.
Upvotes: 3
Reputation: 42017
With awk
:
awk 'NR==FNR {a[$0]=1; next}; !a[$0]' delete.txt file.txt
NR==FNR {a[$0]=1; next}
is only executed for the delete.txt
file (first file argument); associative array a
has the records as keys, and 1
as the value for every key
!a[$0]
is executed for the second file argument i.e. file.txt
; printing (default action) the record(s) that are not present in the array a
as key(s)
Example:
% cat delete.txt
/somedirectory/
/somedirectory2/somefile.txt
% cat file.txt
/somedirectory/
/somedirectory2/somefile.txt
/anotherfile.txt
% awk 'NR==FNR {a[$0]=1; next}; !a[$0]' delete.txt file.txt
/anotherfile.txt
Upvotes: 3