1

I am attempting to remove lines from this text file (foo.txt):

cat
mouse

animals: 2

I want to remove the two lines from the end:

‎
animals: 2

So I end up with this:

cat
mouse

However, when using variable="$(sed '$d' foo.txt)", both lines appear to be removed, even though I only specified one $d. Even though this gives me the result I am looking for, I can't help but wonder why this is happening. When attempting to NOT store the output in a variable, I get the output I expect to see:

user$ sed '$d' foo.txt
cat
mouse

user$

Oddly enough, using $ sed '$d;$d' foo.txt only removes the animals: 2 line, and not the newline before it.

Could somebody de-mystify this for me? Thanks.

For the record, BSD sed is being used in this case.

  • 3
    Command substitution -- the $( ) bit -- removes all trailing newlines from what it captures. Therefore, blank lines at the end will get removed before the value is stored in the variable. (Note: you probably want one newline removed from the end, since lines in a file are normally terminated by newlines, but variable values are not.) – Gordon Davisson Aug 30 '20 at 00:13
  • Thanks Gordon. For the most part, that makes sense. Is there a way for me to retain the newline in between animals: 2 and mouse, while storing the entire thing in a variable? I am using echo "$variable" in my testing. – leetbacoon Aug 30 '20 at 00:30
  • Your issue is with command substitution removing newlines, just like Gordon pointed out. Note also that the d command in sed ends the current cycle. Therefore, on the last line, the code $d; $d would only ever run one d command, never two. It's unclear what the second d would be able to accomplish anyway, as the first d removes the last line. – Kusalananda Aug 30 '20 at 07:06
  • Process substitution will do what you want, e.g. IFS= read -rd '' var < <(tac foo.txt | sed '1,2d' | tac); echo -n "$var" – fpmurphy Aug 31 '20 at 10:29

0 Answers0