LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 01-26-2012, 01:22 PM   #1
JHO5
LQ Newbie
 
Registered: Jan 2012
Distribution: RHEL5/6
Posts: 6

Rep: Reputation: Disabled
Shell Script parse string/match what isn't there


So I've been searching for a while, I'm a bit tired, and finally giving in to writing a post.

I'm writing a shell script (BASH) to do some system file configuration and I need to try and identify if extraneous variables/data have been added to a string...and can't think for the life of me how to do so.

For example within /etc/ssh/sshd_config I have the following line:

Code:
 AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
Now the acceptable values for that line are anything that starts with LC.

So my first move to match that line within sshd_config is:
Code:
 grep -i AcceptEnv /etc/ssh/sshd_config | grep -i LC
That will return the line I mentioned above which is great...but I want to take it a step further. I need to isolate that extraneous data. A grep -v doesn't work because it needs to match a line that has LC and I can't think of an awk command off the top of my head that will show me a match of everything on the line that doesn't match LC*.

In my example, what I'm wanting as a final returned value is just the LANG portion of the string but there are a lot of possible values so I can't just search for LANG because then I'd miss if say someone put XMODIFIERS or any other variable there.

Expected magic expression:
Code:
 grep -i AcceptEnv /etc/ssh/sshd_config | grep -i LC | <awk/grep show matches within string that are not LC*>
Any ideas?

Last edited by JHO5; 01-26-2012 at 01:28 PM. Reason: Added further clarification
 
Old 01-26-2012, 02:52 PM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,551
Blog Entries: 3

Rep: Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815
How about
Code:
awk '(tolower($1) == "acceptenv") {
         for (i = 2; i <= NF; i++)
             if ($i != "LANG" &&
                 substr($i,1,3) != "LC_")
                 print $i
     }' /etc/ssh/sshd_config
You can easily add similar checking for other directives by duplicating the rule. In awk, each rule is applied once for each input record (line by default).

NF is the number of fields (by default, fields are words, anything non-whitespace separated by whitespace). The loop ignores the first field, since that is the AcceptEnv directive. If the field is not LANG, and does not start with LC_, it is printed.

Now, to match your original problem description, you would of course use
Code:
awk '(tolower($1) == "acceptenv") {
         for (i = 2; i <= NF; i++)
             if (substr($i,1,3) != "LC_")
                 print $i
     }' /etc/ssh/sshd_config
instead.

Last edited by Nominal Animal; 01-26-2012 at 02:54 PM.
 
1 members found this post helpful.
Old 01-26-2012, 03:00 PM   #3
JHO5
LQ Newbie
 
Registered: Jan 2012
Distribution: RHEL5/6
Posts: 6

Original Poster
Rep: Reputation: Disabled
Looks like it works - I modified it slightly to be just:

Code:
awk '(tolower($1) == "acceptenv") {
         for (i = 2; i <= NF; i++)
             if (substr($i,1,3) != "LC_")
                 print $i
     }' /etc/ssh/sshd_config
That way I do catch the LANG flag (since that's not a LC* flag)

Thanks! (of course if others have other solutions, that works as well)
As a reference, I ran your code against a RHEL6 box and it returned:
LANG
LANGUAGE
XMODIFIERS

whereas on my default RHEL5 install, it would have just returned LANG (hence why I wanted to be able to capture potential additional flags without knowing what the available flags were).

Last edited by JHO5; 01-26-2012 at 03:04 PM.
 
Old 01-26-2012, 03:14 PM   #4
Cedrik
Senior Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 2,140

Rep: Reputation: 241Reputation: 241Reputation: 241
Same thing with Perl (has not any advantage than awk code posted above)
Code:
perl -ane 'map {print "$_\n"} grep{!/^LC_/} @F[1..$#F] if /AcceptEnv/i' /etc/ssh/sshd_config
 
1 members found this post helpful.
Old 01-26-2012, 03:23 PM   #5
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,551
Blog Entries: 3

Rep: Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815
@Cedrik: This is not criticism, I really want to know: If you saw that stanza, how long would it take for you to parse and grasp what it actually does? It took me almost a minute. Well, half a minute at least. Am I just slow to read perl?
 
Old 01-26-2012, 03:34 PM   #6
JHO5
LQ Newbie
 
Registered: Jan 2012
Distribution: RHEL5/6
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Nominal Animal View Post
@Cedrik: This is not criticism, I really want to know: If you saw that stanza, how long would it take for you to parse and grasp what it actually does? It took me almost a minute. Well, half a minute at least. Am I just slow to read perl?
I'm slow as well - but then again, I don't regularly program in perl. For me, it was mostly the matching AcceptEnv coming at the end that threw me when I first looked at it.

Thanks to both of you for your inputs.
 
Old 01-26-2012, 04:24 PM   #7
Cedrik
Senior Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 2,140

Rep: Reputation: 241Reputation: 241Reputation: 241
Quote:
Originally Posted by Nominal Animal View Post
@Cedrik: This is not criticism, I really want to know: If you saw that stanza, how long would it take for you to parse and grasp what it actually does? It took me almost a minute. Well, half a minute at least. Am I just slow to read perl?
I doesnt take 1 minute !
The input line is autosplited in @F array with -a perl option

The print command line is only executed if input line matches /AcceptEnv/i
(which means match AcceptEnv ignoring case, like grep -i)

@F[1..$#F] : list from @F array, that starts at element 2 and ends at last element of @F
(like in your code, i starts at 2)

grep {!/^LC_/} : return a list of elements extracted from previous list that don't match /^LC_/

map {print "$_\n"} : print each element of list returned by grep with an added newline
(had to do this since perl print function does not add newline by default unlike awk print)

Last edited by Cedrik; 01-26-2012 at 04:29 PM.
 
1 members found this post helpful.
Old 01-26-2012, 08:18 PM   #8
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,551
Blog Entries: 3

Rep: Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815
Quote:
Originally Posted by Cedrik View Post
I doesnt take 1 minute !
Well, half a minute, then

Actually, the issue for me is the structure, not the (sub)expressions. In most programming languages I get an intuitive mental image of the code flow just by looking at a function or a method, without really reading it, within the first second or two.

With Perl, I have to understand each (sub)expression first, then the structure becomes evident. (Although I do avoid Perl nowadays, a decade ago I did have to work with the innards of a couple of Perl projects. I guess I was scarred for life, not because of the language, but because of the projects. So it is not like I'm in any way new to Perl.)

Thanks for your insight, though. I find it very interesting that you chose to describe the subexpressions in right-to-left order. It would be very interesting to do some statistical research (perhaps even here on LQ), and see if certain features, like tendency to use distinct language features such as unless, has correlation to programming language preference or proficiency.

Returning back to the original topic, I do believe that seeing and discussing differing alternate solutions to a problem is always fruitful. Therefore I repeat: thank you.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] How to parse and modify these keywords using shell script? corone Programming 17 04-26-2011 07:33 AM
Parse String in a Bash script jimwelc Linux - Newbie 6 04-01-2009 01:48 PM
any gdb script to parse string? jackandking Linux - Software 3 12-07-2008 11:19 PM
Bash script: Parse folders in path string miceagol Programming 3 03-25-2008 06:31 PM
Shell Script: Delete lines til string found or until particular string. bhargav_crd Linux - General 3 12-20-2007 11:14 PM


All times are GMT -5. The time now is 03:57 PM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration