20

This works fine on Linux (Debian):

sed -e 's,^[ \t]*psd\(.*\)\;,,' 

On mac, I believe I have to use the -E flag, instead of -e:

sed -E 's,^[ \t]*psd\(.*\)\;,,'

but the regexp does not match, and hence does not remove the lines I want.

Any tips on how to solve this?

Sample input:

apa
bepa
    psd(cepa);
depa psd(epa);
  psd(fepa gepa hepa);

For that input, the expected output is:

apa
bepa
depa psd(epa);
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JohnSmith
  • 4,538
  • 9
  • 25
  • 25

5 Answers5

15

The -E flag means to use extended regular expressions. You should just use -e, as on Linux. The sed in Mac OS X is based on BSD sed, so doesn't have the GNU extensions.

After copying your sample input:

[~ 507] pbpaste | sed -e 's,^[[:space:]]*psd\(.*\);,,'
apa
bepa

depa psd(epa);
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Michael J. Barber
  • 24,518
  • 9
  • 68
  • 88
  • 2
    `-E` also works on gnu sed, it's an undocumented option they added to be compliant with posix – NDM May 03 '17 at 13:20
9

Alternatively you can use the GNU version of sed instead of the implementation provided by Mac OSX.

Mac port provides a port for it sudo port install gsed. After installing it you can use gsed instead of sed.

a.b.d
  • 2,190
  • 3
  • 26
  • 26
  • 10
    Or `brew install gnu-sed --default-names` for brewing people :) – Anton Babenko May 12 '14 at 21:25
  • 3
    For those who like @AntonBabenko's, just note that `--default-names` is deprecated in recent versions. Use `brew install gnu-sed --with-default-names` **and then reopen your terminal** instead. – Bilal Akil Jun 30 '15 at 12:25
  • 2
    Homebrew's `--with-default-names` option has been deprecated. (so have all options on official formulae). But you can make your own alias just by doing `ln -s /usr/local/bin/gsed /usr/local/bin/sed`. But personally I wouldn't do this. Some shell script might rely on the behavior of the built in BSD `sed` and you might end up with some mysterious problems because of this. – Chris Jan 19 '21 at 01:50
8

The '\t' is not standard in 'sed', it is a GNU extension.

To match a 'tab', you need to put a real 'tab' in your script. This is easy in a file, harder in shell.

The same problem can happen in AIX, Solaris and HP-UX or other UNIXes.

jfg956
  • 16,077
  • 4
  • 26
  • 34
  • 6
    I missed that in my answer. You can always use POSIX character classes, either `[[:space:]]` or `[[:blank:]]` would work. To get a literal tab in the shell, pressing ctrl-v will give you a literal for the next character. – Michael J. Barber Jul 20 '11 at 14:43
4

In addition to the answers above, you can exploit a useful (but shell-dependent) trick. In bash, use $'\t' to introduce a literal tab character. The following works on my Mac:

sed -e 's,^[ '$'\t''*psd\(.*\);,,'

Note how the whole sed expression consists now of three concatenated strings.

This trick might be useful in case you need the tab character specifically, without matching other whitespace (i.e., when [[:blank:]] would be too inclusive). For the above, the -e flag is not essential.

waku
  • 111
  • 1
  • 4
2

I've check this sample input on my machine and faced the problem when in third line was tab character from the beginning of line and regexp ^[ \t]*psd\(.*\)\; didn't match it. This can be passed by sed character class [[:blank:]] that equal combination of space and tab character. So you can try the following:

sed -E 's,^[[:blank:]]*psd\(.*\)\;,,' demo.txt

this produce the following output:

apa
bepa

depa psd(epa);

but it keeps the empty lines in result. To get the exact output as you expected I used the following:

sed -n '/^[[:blank:]]*psd\(.*\)\;/!p' demo.txt

result:

apa
bepa
depa psd(epa);

this is just inverse output of matching pattern (!p).

EDIT: To match tab characters in regexp in sed (macosx) you can also try recommendation from How can I insert a tab character with sed on OS X?

Community
  • 1
  • 1
user478681
  • 8,330
  • 4
  • 26
  • 34