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'm pretty good at using php's preg_match (and similar) commands, and I'm also pretty good with regular expressions, but I don't do very well with sed.

I have two shell scripts I'm working on and I'd like to be able to pull some variables out of configuration files.

First File

The first file is an .htaccess file and I want to grab the web address, which is going to be in a block that looks like this:

RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]

The syntax of the .htaccess file is going to be pretty regular so I feel like I should use a pattern similar to #.*(http.*?)\$#is which does:

  • regular expression
  • delimited by #
  • 0 or more characters before http
  • start capturing at the http with the non-greedy symbol ?
  • continue capturing until you hit an actual dollar sign (escaped)
  • match case insensitive
  • ignore whitespace / newlines

How can I use that regular expressionwith a command like sed so that I get the part inside parenthesis if it matches, and nothing (empty string) if it does not match?

Would I be better off using another command besides sed if I am used to php's PCRE?

Second File

The second file is a little different because it is an .ini file and so I wonder if there might be some shell magic (I use bash) in order to parse it. The chunk I want looks like this:

[Database]
database          = mysql://user:password@localhost/database

If I was using PHP and regular expressions I would do something like this:

#\s+database\s*=\s*mysql://([\:]+):([\@]+)@([\/]+)/(.*?)\s+#is

In PHP there is an .ini parser, but I want this to be a shell/bash script, not a PHP script

How can I use that regular expression to get the database connect credentials?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

If you want to use perl-like regular expressions, why not use perl (which is found on 99% of non-embedded Unices)?

Like:

perl -lne 'print for /(http.*?)\$/'

perl -lne 'print for m{database\s*=\s*mysql://([^:@]+):([^@]+)@([^/]+)/(\S+)}i'

/.../ is the shorter form of m/.../. The m/.../ one allows other characters than / and also pairs like m{...}, m(...).

something for @list runs something looping as the $_ variable on the values of the list. m{...} in list contexts returns the list of captured patterns (inside (...)). print without arguments, prints $_.

share|improve this answer
    
can you elaborate on the for and m{}i parts of the syntax? –  cwd Nov 27 '12 at 20:57

Try

grep -oP <your_pattern> <your_file>

The -P ensures that grep will interpret your regex a la Perl and -o makes it return only what it has matched.

EDIT: Note that your grep may not necessarily support lazy quantifiers, so if you don't expect URLs to run over multiple lines, I'd use a greedy quantifier without the /s modifier.

share|improve this answer
    
that look very good! and with my good friend grep to boot! i'm going to give it a try! thanks! –  cwd Nov 27 '12 at 19:37
    
I seem to be having a hard time getting grep to return only the part in the parenthesis –  cwd Nov 27 '12 at 20:14

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.