Strip off word pattern at the end of string using sed

8,061

Solution 1

sed -e 's/& PID=\$\!;$//'

The $ toward the end anchors it to the end of the string.

Solution 2

All answers are good so far, but for this concrete example you can save your time and write a few characters less:

sed 's/ & [^ ]*$//'

or even better

sed 's/ & \S*$//'

Solution 3

To remove the last occurrence of a pattern on a line, you can just squeeze it.

sed 's/\(.*\)& PID=$!;/\1/'

That will match as much as possible in \1 before matching the string so it will always strip only the last occurrence - regardless of whether or not the string you strip is actually at the end of the line.

Your attempt:

 sed 's/\(\& PID=\$\!\).*$//'

...does something like the opposite. It strips all characters on a line beginning with the first occurrence of your string and following on to the end of the line.

Remember the leftmost-longest rule - a regexp will always begin its match as far to the left in the string as it might and continue to match for as long as it might.


Note that if you want to remove just n last characters then with gnu sed

sed -E 's/.{9}$//'

Here -E option is necessary to use extended regular expressions.

Share:
8,061

Related videos on Youtube

Sas
Author by

Sas

I am a new grad software engineering student with big dreams. I consider myself an infant in programming, that does not mean I won't grow up. I enjoy every aspect of programming (coding, troubleshooting, bug fix, system design, etc). Quote: "Typing is no substitute for thinking." — Dartmouth Basic manual, 1964.

Updated on September 18, 2022

Comments

  • Sas
    Sas over 1 year

    I have following string:

    ksh -x SCRIPT2.ksh $BUSSINESSDATE & PID=$!; ksh -x SCRIPT1.ksh $BUSSINESSDATE & PID=$!;
    

    I want to strip off the last word & PID=$!;. Desired result is:

    ksh -x SCRIPT2.ksh $BUSSINESSDATE & PID=$!; ksh -x SCRIPT1.ksh $BUSSINESSDATE
    

    Note: that I do have & PID=$!; in the middle of the string, I only need to get rid of the last word which contains & PID=$!;

    I am using sed achieve this. But it doesn't seems to produce the expected output.

    sed 's/\(\& PID=\$\!\).*$//'
    
    • Costas
      Costas over 9 years
      Try sed 's/& PID=$!;\s*$//'
    • Sas
      Sas over 9 years
      @Costas It works. But wondering what does "\s" in the middle does in your command?
    • janos
      janos over 9 years
      \s* is zero or more white-space characters. You might not need it. It seems Costas was being extra careful.
  • jimmij
    jimmij over 9 years
    @mikeserv .{9}$ is only 5, so definitely the best one! :)
  • mikeserv
    mikeserv over 9 years
    @jimmij - you should probably give up the -r habit. The -E syntax is compatible with GNU and BSD seds and should be POSIX as well if/when this ever takes effect.
  • jimmij
    jimmij over 9 years
    Yes, probably. But -E is not documented neither in man nor in info, at least for my GNU sed version 4.2.1.
  • mikeserv
    mikeserv over 9 years
    @jimmij - yup, that remains an undocumented feature*(?)*. And it actually is slightly less capable - as near as I can tell the only thing you can do with -r that you cannot do w/ -E is switch from a BRE context to an ERE context. With -r you can do sed -e 's/BREhere\(.*\)/w \1 portable backrefs/' -er 's/(nowERE).*/and \1 backrefs only as a non-POSIX extension/'. While the backrefs w/ ERE still work w/ -E you can't switch from BRE to ERE like that. And even w/ -r you can't switch back to a BRE context anyway.