adbar
adbar

Reputation: 446

Bash - delete rows from one file while iterating through rows from another file

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

Answers (4)

rom1v
rom1v

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

Zumo de Vidrio
Zumo de Vidrio

Reputation: 2091

With a simple grep:

grep -vFxf  delete.txt file.txt > temp.txt && mv temp.txt file.txt 

Upvotes: 5

Tim Tjarks
Tim Tjarks

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

heemayl
heemayl

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

Related Questions