sed doubt in extracting

Hi,

Can anyone help me in understanding how the below code works?

echo "texxt" | sed 's/[^x]//' 

gives output exxt, ideally it should give xxt. as this should remove the chars which is not x.

echo 'x_a_b_a_c_a_d' | sed 's/.*\(a\)/\1/' 

gives output as a_d, which should be 'a' as it's the only character in the section

echo 'foo-bar-1.4.5-19.spkg' | sed 's/-[^-]*$//'

and how the above code works?

try

echo "texxt" | sed 's/[^x]//g' 

the output is normal. You ask to replace all characters up to the last a in string. Remember the sed regex are "greedy". They take all they can.

Same as above. That pattern will take all non - characters following a - up to the end of the string. The only part of the string that match that pattern is from the last - up to the end.

s/[^x]//g

This means "replace the first character which isn't a 'x' with nothing". Since that's done as soon as the first 't' is replaced, sed is finished. If you want to remove all characters leading up to the first 'x', use

s/[^x]*//g

In the second snipped:

echo 'x_a_b_a_c_a_d' | sed 's/.*\(a\)/\1/'

you're replacing as many characters as possible from the start until the last possible 'a' with the matched 'a'. The rest of the string isn't affected, so 'x_a_b_a_c_a' is replaced by 'a', which changes 'x_a_b_a_c_a_d' to 'a_d'

Third:

echo 'foo-bar-1.4.5-19.spkg' | sed 's/-[^-]*$//'

means "starting with a dash, take as many non-dash characters as possible until the end, and replace them with nothing", or "remove everything starting from and including the last possible dash".