0

I want to pipline cat output of file to a sed pattern. Suppose I have 2 files: color.txt and duplicate.txt. color.txt contain 3 colors: blue, green, red and duplicate.txt contains green. I want to use sed to delete green from color.txt file.

I try something like this:

cat duplicate.txt | sed "/$/d" < color.txt

Unfortunately, it doesn't work. Any suggestions how to do this?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Bartosz Kozak
  • 11
  • 1
  • 2
  • 1
    *nix utils can generally work on files and using cat in this way is broadly considered to be a "[UUOC](http://porkmail.org/era/unix/award.html)" ... a "useless use of cat". As you'll see in the answers (so far) they generally don't use `cat`. – Stephen P Sep 13 '17 at 22:29

3 Answers3

2

You can use grep to achieve what you want:

grep -Fxvf duplicate.txt color.txt
  • -F to treat lines in duplicate.txt as strings rather than patterns
  • -x to match whole lines in color.txt
  • -v to extract lines that don't match
  • -f to pick up strings from duplicate.txt to match against color.txt

This will work irrespective of how many patterns your files have. For extremely large files, you might want to take a look at this post:

codeforester
  • 39,467
  • 16
  • 112
  • 140
2

While in this case the grep solution is enough, sometimes I use a command like this:

sed 's|.*|/^\1$/d|' duplicate.txt | sed -i -f - color.txt

Here the first sed invocation converts each line from duplicate.txt into a proper sed command to delete exactly what needed. This results in a sed script that is then passed to second sed using -f - where the - file name means standard input.

aragaer
  • 17,238
  • 6
  • 47
  • 49
0

I think you mean this:

sed "/$(cat duplicate.txt)/d" color.txt

However, as you can tell from the comments, this approach is not very advisable. I urge you to use one of the other solutions. I won't delete this answer though, as it does show the technique you wanted to learn.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • 2
    Wouldn't this give a syntax error if duplicate.txt has more than one line? Also, it will delete lines that match partially as well. Not sure if that's what OP wants. – codeforester Sep 13 '17 at 18:55
  • @codeforester Yes, I took the question to mean there was only one line because of the example given and the fact that it is called *"duplicate"* and not *"duplicates"*. Although I guess by that logic, it should be *"colors.txt"* but it isn't:-) – Mark Setchell Sep 13 '17 at 18:58
  • The partial matches could be overcome by adding word boundaries, but again OP wasn't specific on that matter. I was trying to demonstrate the technique OP was asking about - namely how to use contents of a file as the pattern for `sed`. I agree your solution is technically more accurate, mine is closer to the concept OP appeared to be trying to achieve - going by the title. I'll vote for yours – Mark Setchell Sep 13 '17 at 19:03
  • 1
    I hope the color doesn't has a slash, like `terrible/red`. – Walter A Sep 13 '17 at 21:54