6

I am trying to remove the first occurence of digit(s), the dot, the second occurence of digit(s) and the space before the word.

I have come up with this regex:

sed 's/^[0-9]\+.[0-9]\+\s//' input.txt > output.txt

Text sample:

2.14 Italien
2.15 Japonais

My regex does not work unfortunately. There is a problem with the \s but I can't pinpoint what it is...

Can anyone help?

edit: The problem is that I need to remove the first space only as some text contain spaces as you can see below:

3.15 Chichewa
3.16 Chimane
3.17 Cinghalais
3.18 Créole de Guinée-Bissau
6
  • Do you actually just want to get the second column?
    – slhck
    Mar 31, 2013 at 18:55
  • Seems to work as intended with GNU Sed 4.2.1. Perhaps putting the character class in "range" brackets would help? such as: [\s]\+ Also, the dot has special meaning when not escaped, you may want to look out for that. Mar 31, 2013 at 19:05
  • @ЯрославРахматуллин How can this work with a plain GNU sed call when the OP uses ERE metacharacters (+), and extended RE aren't enabled by default?
    – slhck
    Mar 31, 2013 at 19:20
  • 1
    @slhck: Those are GNU extensions. If you escape the plus, you don't need the -r switch; and to make it more confusing, you cannot escape the plus with sed -r. \s works as well. Both stop working with the --posix switch.
    – Dennis
    Mar 31, 2013 at 19:37
  • Not sure, the /usr/share/doc/sed-4.2.1-r1/NEWS.bz2 (Gentoo) file kind-of suggests that the --posix option is required for the "standard" behavior, although the manual does say -r is required for extended regexps to work... Mar 31, 2013 at 19:37

5 Answers 5

12

The command you're using should work as-is with GNU sed. But with BSD sed, which for example comes with OS X, it won't.

  • If you're trying to use Extended Regular Expressions – which support the + metacharacter – you need to explicitly enable them. For BSD sed you do this with sed -E, and for GNU sed with sed -r.

    The \+ alone does with GNU sed when EREs are not enabled, but this is less portable.

  • You're using the Perl-like \s, which doesn't exist for both Basic and Extended Regular Expressions. Regular sed doesn't support Perl regular expressions though. GNU sed does support the \s – but it'd be more portable to simply add the space to your regular expression.

  • Finally, your . matches one character, so your regex would even match any character in that place, not just a dot. Use \. to properly escape it.

So, a solution would be, for GNU sed:

$ echo "2.12 blah" | sed -r 's/^[0-9]+\.[0-9]+ //'
blah

Or for BSD sed:

$ echo "2.12 blah" | sed -E 's/^[0-9]+\.[0-9]+ //'
blah

This way you don't need a different regex for different versions of sed. With your example:

$ cat test
3.15 Chichewa
3.16 Chimane
3.17 Cinghalais
3.18 Créole de Guinée-Bissau

$ sed -r 's/^[0-9]+\.[0-9]+ //' test
Chichewa
Chimane
Cinghalais
Créole de Guinée-Bissau

If the real problem is that you want to get the second column of a whitespace-delimited file, then you're going about this the wrong way. Either use awk, like @Srdjan Grubor says, or use cut:

$ echo "2.12 foo bar baz" | cut -d' ' -f2-
foo bar baz

The -f2- specifies the second and all following columns, so this will basically take the first space as the separator and output the rest.

9
  • I run GNU sed and have tried the -r switch as follows: sed -r 's/[0-9]+\.[0-9]+ //' input.txt > out.txt to no avail.
    – balteo
    Mar 31, 2013 at 21:16
  • Hi slhck: Thanks for the detailed reply. FYI, I use Ubuntu and GNU sed.
    – balteo
    Mar 31, 2013 at 21:28
  • I've tested all of the examples, also with GNU sed. What specifically doesn't work? What result do you get? The most straightforward solution in your example would be cut -d' ' -f2- though.
    – slhck
    Mar 31, 2013 at 21:33
  • 1
    Your input is not formatted as you said it was. Please check that more thoroughly: After the numbers, you have a U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX and then a U+00A0 NO-BREAK SPACE, not just a single whitespace. A sed -r 's/^[0-9]+\.[0-9]+ //' input should do, if you copy whatever is the space between your numbers and the string into the actual command.
    – slhck
    Mar 31, 2013 at 21:41
  • 1
    The POSIX-y equivalent for perl's \s is [[:space:]] Mar 31, 2013 at 23:09
7

Why not use awk?

cat  input.txt | awk '{print $2}' > output.txt
2
  • Hi Srdjan: Thanks for your reply. I have edited my post to further specify my problem.
    – balteo
    Mar 31, 2013 at 21:17
  • See my comment to slhck. Sorry.
    – balteo
    Mar 31, 2013 at 22:02
2

If the only thing is to drop everything upto and including the first space then this suffices

sed -e 's/[^ ]* //'
3
  • This would work without the digits but not in this case.
    – balteo
    Mar 31, 2013 at 21:22
  • Using this: sed -r 's/[^ ]//' on a file with only a leading whitespace produces the desired effect.
    – balteo
    Mar 31, 2013 at 21:26
  • See my comment to slhck. Sorry.
    – balteo
    Mar 31, 2013 at 22:02
1

You could also use grep:

grep -oP '[a-zA-Z]+$' input.txt > output.txt

1

With any sed:

sed 's/^[0-9]\{1,\}\.[0-9]\{1,\} //' 

Or perhaps this might suffice:

sed 's/^[0-9.]\{1,\} //' file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .