1

I'm new to sed, I have a string

lightdm --session-child 14 21

the two numbers can change and I would remove everything after lightdm

I tried various way but none worked

sed 's/ --session-child*//'
sed 's/\ --session-child*//'
sed 's/ --session-child*$//'

and others, but none worked where is wrong ?

2
  • 1
    You appear to be confusing shell wildcards (where * matches zero or more characters) with regular expressions (where .* matches zero or more characters) - see for example Why does my regular expression work in X but not in Y? Commented Mar 15 at 21:23
  • @steeldriver ok Commented Mar 15 at 21:34

1 Answer 1

5

* in regular expressions means "repeat the previous character (or character class) arbitrary many times. So, --session-child* matches

  • --session-chil
  • --session-child
  • --session-childd
  • --session-childdd
  • --session-childddd
  • I think you see where this is going.

However, it does not match --session-child 1, because a is not a d! (and neither is a 1, but that doesn't matter at that point anymore. The streak of d is broken.)

If you want to say "any single character", that's a . in regular expressions. If you mean "arbitrarily many arbitrary characters", that's .*.

So, you'd need sed 's/ --session-child.*//'

However, I tend to advocate for matching the things you want instead of erasing the things you don't want. I don't know what you originally intended, but assuming you wanted to preserve anything before the first space, I'd write that as sed 's/^\([^ ]*\) .*$/\1/'. Meaning: from the beginning of the line (^), start a new group (encapsulated in \(\)). That group contains any character that is in the character class (enclosed in []) described by ^ , which means "everything but" (^) the space character . Repeat that as many times (0 or more) if possible (the first *).

If a space comes after that, absorb that space and all characters until line's end ($) and replace them with the first (and only) matched group, \1.

That's way more effort to write down. Why would I do that? Because writing down what you not want is often a mental exercise that involves assumptions that are not inherent to the actual problem. For example, here you assume that the first argument to whatever comes before is --session-child. Now, if that "whatever" isn't lightdm, why would it take a --session-child argument? And if it always was lightdm why, would you use sed at all? You would just output lightdm. So, by not making assumptions on a "cute little side fact" but focusing on what I really care about, I can avoid future bugs with input I didn't expect.

2
  • Yes, I'm trying to understand how sed and awk works and sed 's/ --session-child.*//' works. I will study sed 's/^\([^ ]*\) .*$/\1/' to better understand it Commented Mar 15 at 21:36
  • ...and if all you want is just the first argument, using awk instead might be easier: awk '{print $1}' Commented Mar 17 at 0:56

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.