Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Using [[:space:]] looks a little non-elegant and, quite frankly, Microsoft-ish for sed match patters. I was trying to extract "Last" out of "First Last" and either of the following worked:

echo "First Last" | sed s/First //
echo "First Last" | sed s/First\s//

What did work is

echo "First Last" | sed s/First[[:space:]]//

I was wondering:

  1. Is there is a more minimalistic notation to match a whitespace in sed?
  2. Does [[:space:]] work on all Linux distros?
share|improve this question
2  
"Microsoft-ish"? That's a classic BRE character class, it's as POSIX as it gets. –  terdon Feb 6 '14 at 17:36
    
i just find \s to be more minimalist –  amphibient Feb 6 '14 at 17:38
    
That's specific to PCREs, you won't find it anywhere else. –  terdon Feb 6 '14 at 17:42
    
it works with Java, Perl and Python RegEx patterns. –  amphibient Feb 6 '14 at 17:43
2  
By the way, the problem with echo "First Last" | sed s/First // is that you are passing two arguments to sed. You need to quote the argument: echo "First Last" | sed "s/First //" or echo "First Last" | sed s/First\ // –  rici Feb 6 '14 at 18:11

2 Answers 2

up vote 5 down vote accepted

Yes, [:space:] should be recognized by all sed editions, it is part of Basic Regular Expressions as defined by POSIX.

The \s notation is from Perl Compatible Regular Extensions which are implemented in many programs (grep with -P for example) and languages (perl, php, java, javascript, python...). Neither one of these regex syntaxes has anything to do with Microsoft!

If you want PCRE syntax, why not use Perl? Both of these work:

echo "First Last" | perl -pe 's/First\s//'
echo "First Last" | perl -pe 's/First *//'

The -p flag means "print every line" after performing whatever script was passed with -e on it.

share|improve this answer

BRE syntax is non-elegant where some other variations are elegant because BRE is designed to be easily abstracted. BRE is simply parsed - a programmer implementing his/her own BRE-based grammar subset need never worry if the match string \s is meant to indicate a \backslash followed by an s or the [[:space:]] character class - because the former is always true. It is for this very same reason that syntax expressions are those that are \(escaped\) as opposed to (literal chars), and why \backslashes lose their special meaning within [char classes].

If you think this explanation something of a stretch, please first consider how simply it is actually done...

dot_whole_words()(
    s=[:space:] b=[:blank:] w=_[:alnum:] z1=\\{0,1\\}
    sed "G;s/[$b]*\([$w]*[^$w$s][^$s]*\)$z1\([$w]*\)[$s]/.\2/g"
)

That little shell function will pick out only whole words from an input line and separate those found with one or more .dots on output.

echo 1 2 3 four five si.x se\$Ven eight 9nine\! |
dot_whole_words

.1.2.3.four.five...eight.

It does annoyingly drop all words that have even a single punctuation point attached, as is evinced by 9nine! failing to come across. This can also be handled with some additional abstraction.

whole_words_imp()(
        s=[:space:] b=[:blank:] w=_[:alnum:] p=[:punct:]
        z1=\\{0,1\\} p1=\\{1,\\} pn=[$p]$z1
        cs=\\\([$w]* ce=\\\)
        wd=$cs$ce    ce=$ce$z1
        nwd=$cs[$p][^$s]$p1$ce
        nwd=$nwd$cs[^$w$s$p][^$s]*$ce
        sed -ne:n -e'$!{N;/\n$/!bn' -e\} -eG \
                  -e"s/[$b]*$pn$nwd$wd$pn\([$s]\)$p1/\3\4/g" \
                  -e"/[^$s]/s/[$s]$p1/ /gp"
)

Now that version will read input a paragraph at a time, and, when it has found a blank line, it will reduce all of the input read so far to only words as might be composed of any number of [$w] chars, and which might be lead or trailed by at most one punctuation mark on either end.

For example:

printf %s\\n 1 2 3 \
       four five   \
       si.x se\$Ven\
       eight 9nine\! |
whole_words_imp

1 2 3 four five eight 9nine

And so, as I hope you can see, BRE is only as elegant as you make it to be.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.