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.

I am confused with sed.
I had a file with the following contents:

[ 2014/02/10 14:45:15 | INFO   ] Saving data for customer: 273667  
[ 2014/02/10 14:45:15 | INFO   ] Saving data for customer: 273687  
[ 2014/02/10 14:45:15 | INFO   ] Saving data for customer: 272667  
[ 2014/02/10 14:45:15 | INFO   ] Saving data for customer: 373667  
[ 2014/02/10 14:45:15 | INFO   ] Saving data for customer: 573667  
[ 2014/02/10 14:45:15 | INFO   ] Saving data for customer: 263667  

I wanted to remove everything except the customer id. So I run the following:

$ sed 's/^.*:\s\(\[0-9\]\{6\}\)/\1/g' customers.txt > customers2.txt  

This did not do absolutely anything.
After thinking about it (and a lot of frustration) I tried to remove the escapes from the []. So I run the following:

$ sed 's/^.*:\s\([0-9]\{6\}\)/\1/g' customers.txt > customers2.txt    

This worked.
But now I can not really undestand how sed works. Why do I need to escape ( for grouping and { for range but not [ for the character class?

share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

Basically, because [ ] is part of the basic regular expression syntax while capture groups and {} are not. Escaping [] means you want to match a literal bracket, not a class.

As an aside, if what you want is to print the last field in a file, awk is much easier:

awk '{print $NF}' customers.txt > customers2.txt    

In your particular case, you could also use cut:

cut -d':' -f 4 customers.txt > customers2.txt    

and you can always use Perl:

perl -pe 's/.*:\s*//' customers.txt 
share|improve this answer
    
Is this related to POSIX or NFA/DFA? –  Jim Feb 10 at 21:51
    
@Jim this is related to BRE, basic regular expressions which are defined in the Single Unix Specification Version 2. –  terdon Feb 10 at 21:57
add comment

For historical reasons. In the first version of Unix, only the characters \[.*^$ had a special meaning in regular expressions. When newer features were added (option \?, repeat at least once \+, repeat count \{…\}, groups \(…\), alternation \|), these could not make the characters ({| special because it would have broken compatibility with existing scripts that used these characters literally. So basic regular expressions and tools that build on them used backslash+character combinations that were not in use at the time.

Extended regular expressions broke compatibility in the interest of a consistent syntax.

share|improve this answer
add comment

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.