Results 1 to 10 of 10
Is there a way to incorporate awk as an "if" test-command?
As a basic example:
I need to find a line that contains peanuts, elephant and clowns, such as this ...
- 01-15-2010 #1Just Joined!
- Join Date
- Jan 2010
- Posts
- 12
Using awk for an IF test?
Is there a way to incorporate awk as an "if" test-command?
As a basic example:
I need to find a line that contains peanuts, elephant and clowns, such as this line:
awk '/peanuts.*elephant.*clown/' events.txt
If the file does contain a line with all three words I'm going to echo "The circus is in town"
If there is not a matching line than I need to
awk '/Talladega.*NASCAR.*Cup/' events.txt
and if that exists I will echo "There's a race this weekend!"
If it does not exist I wantt to just echo something and kill the script.
I have no problem with the if, then and else part of it. I just can't seem to come up with the correct syntax to use awk as a test on if.
- 01-15-2010 #2Linux User
- Join Date
- Nov 2009
- Location
- France
- Posts
- 292
Code:if [ -n "$(awk '/pattern/' file)" ]
- 01-15-2010 #3
So this can be done with awk. The problem is that awk is a complicated tool with fun syntax, the ability to modify lines, and deal well with fields. You may notice that most of these are not what you need.
There is a much simpler tool that will be easier for you.
The tool "grep" takes a bunch of input and looks for a specific pattern inside of it. This is exactly what you need.
In your particular case, you could do this:
In this syntax, grep takes a pattern and a text file and searches for a line containing the requested pattern. Normally, grep would then print out that line.Code:if grep -q 'peanuts.*elephant.*clown' events.txt; then echo "The circus is in town!" elif grep -q 'Talladega.*Nascar.*Cup' events.txt; then echo "There's a race this weekend!" else echo "There are no events. Sorry." fi
However, by using the "-q" option (which was built specifically for this purpose), we tell grep to not print anything, and instead simply notify us if a match was found. This allows for simple constructions like the above.
I hope this helps you out.DISTRO=Arch
Registered Linux User #388732
- 01-16-2010 #4Just Joined!
- Join Date
- Jan 2010
- Posts
- 12
This works okay nmset. Actually I was stumbling all over this on my own. Close but no cigar. I eventually discovered some errors in my patterns and some quote marks misplaced.
I do have one question. I note you are using -n here. Strange as it seems, my list of "primaries" that I obtained from the net does not have this. It does have a -N
I googled a bit and it seems -n tests to see if the argument is non empty. I just found it unique that my laundry list has -f -d -k -p -r, etc. but no -n so, I added it.
- 01-16-2010 #5Just Joined!
- Join Date
- Jan 2010
- Posts
- 12
Thanks for the info Cabhan and the grep suggestion. I will test your code later this evening.
I do see what you mean about it being much simpler and less aggravating to construct.
Do I assume here that with these patterns grep will come up true if it finds elephant, elephant47, 45elephant89 if any exist? If so, is there a way to force grep to just key in on elephant and nothing more. Brackets like used in a range maybe?
- 01-16-2010 #6
So in your original awk statement, you used a pattern which I used as well in my grep example. These patterns are called regular expressions. Regular expressions tend to work the same across all utilities that use regular expressions, so the behaviour of a match in awk should be the same as a behaviour as a match in grep.
In the pattern /peanuts.*elephant.*clown/, the ".*" bits mean 0 or more of any characters. You could also read ".*" as "some amount of anything". So this regular expression matches any of the following:
If you want to check for a line that contains only the word "elephant", you could use a regular expression such as /^elephant$/. "^" means the beginning of the line and "$" means the end of the line. Therefore, this looks for a line that is simply "elephant".Code:peanutselephantclown peanuts LA LA LA LOOK AT ME elephant WOULDN'T YOU LIKE A clown There will be peanuts, an elephant, and a clown ...
Did I understand your question correctly? Does this help?DISTRO=Arch
Registered Linux User #388732
- 01-16-2010 #7Linux User
- Join Date
- Nov 2009
- Location
- France
- Posts
- 292
[ -n $SOMEVAR ] is a test on a variable. You could also writeI do have one question
without square brackets.Code:test -n $SOMEVAR
for all available tests. The test utility is intended to be used with single or multiple variables, or with files.Code:man test
But, as fo awk usage, using grep would be simpler in this case.
- 01-16-2010 #8Just Joined!
- Join Date
- Jan 2010
- Posts
- 12
I'm not totally sure if you did fully but you did hit upon some of what I am getting at. I understand we are dealing with patters here. A search for car will find car, cargo, boxcar, etc. and I get your jest concerning the /^elephant$/ but what happens if I need to find a line that contains elephant, peanut and clown and no derivatives such as peanuts, elephantiasis, clowned, etc. Is there something I can use for start and end of word in the same manner one can limit end and/or start of line?
- 01-16-2010 #9
Ah, I see what you mean, and the answer is "it depends on the tool". I know that I said regexes are generally the same everywhere, but that technically isn't true.
There are a few regex standards. The first is POSIX regexes, which are what awk, sed, grep, etc. use by default. These are fairly basic. You then have Extended Regular Expressions, which add some additional features. You then have non-standard ones, such as Perl regular expressions. These add additional features that are very helpful, but which may not be recognized everywhere.
grep, for instance, recognizes the \< and \> anchors, which mean the beginning and the end of a word respectively. So the regular expression /\<elephant\>/ will match the following lines:
However, it will *not* match the following:Code:elephant There is an elephant. I want an elephant, but they are expensive.
This feature is also recognized in vim, for instance. Perl uses \b to mean a word boundary (grep recognizes this as well, but \< and \> are a bit more specific).Code:elephants 32elephant.
Note that a "word" in this case is generally recognized as the regular expression /[0-9A-Za-z_]+/, though grep might use /[0-9A-Za-z]+/ instead.
Does this help?DISTRO=Arch
Registered Linux User #388732
- 01-18-2010 #10Just Joined!
- Join Date
- Jan 2010
- Posts
- 12
Yes Cabhan, this does help very much and is what I was specifically after. What I am scripting alters a user's configuration file and it needs to be precise and totally accurate.
I appreciate all the information you've provided and also appreciate the time you've taken to explain this with a bit more depth.
Speed


Reply With Quote
