LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   BASH string parsing - why so difficult? (https://www.linuxquestions.org/questions/programming-9/bash-string-parsing-why-so-difficult-913820/)

nenpa8lo 11-16-2011 06:22 AM

BASH string parsing - why so difficult?
 
Hi All,

I want to parse a string in BASH to check if a word 'error' is in it. And if it is I do not print message.

Code:

VAR=$(command);
if [ !strstr($VAR,'error') ]; then
  echo $VAR;
fi

My background is C so I came up with strstr(). I've checked a number of websites and it seems like mission impossible to do some sort of simple string compare in BASH. And as I'm running my script on embedded linux, I'm resource constraint and cannot make huge statements with files/pipes and so on... Is it possible?

colucix 11-16-2011 06:26 AM

As you noticed strstr is a C function, not BASH. In BASH you can try:
Code:

if [[ ! $VAR =~ error ]]; then echo $VAR; fi
or using grep
Code:

if ! echo $VAR | grep -q error; then echo $VAR; fi

unSpawn 11-16-2011 06:26 AM

VAR=$(command 2>&1); [ "${VAR}" = "${VAR//error/}" ] && echo "${VAR}"

nenpa8lo 11-16-2011 06:35 AM

Thank you! But there are issues:

@colucix - ./test.sh: 5: [[: not found

@unSpawn - ./test.sh: 5: Bad substitution

colucix 11-16-2011 06:45 AM

Which version of BASH are you using?

unSpawn 11-16-2011 06:56 AM

Quote:

Originally Posted by nenpa8lo (Post 4525474)
./test.sh: 5: Bad substitution

I can reproduce that error using a Bourne Shell. 'VAR=`somecommand`; echo $VAR | { grep -q error || echo $VAR; }; ' should work regardless.

Juako 11-16-2011 08:35 AM

Check the hashbang at the top of the script,
Code:

#!/bin/sh
Invokes the Bourne shell or, in case Bash is symlinked to /bin/sh invokes Bash in "compatibility mode". My take is that bash in compat mode won't recognize bash-specific constructs like [[ ]].

If you want to use "bashisms", change the hashbang to:
Code:

#!/bin/bash
Or otherwise use only POSIX/sh compatible code.

http://mywiki.wooledge.org/Bashism
http://www.gnu.org/s/bash/manual/htm...OSIX-Mode.html

nenpa8lo 11-16-2011 08:39 AM

Code:

echo $VAR | { grep -q error || echo $VAR; };
works for me in BASH. But as I said I'm using embedded linux which means busybox and busy box complains about this line saying VAR: not found.

My fault I should not title the subject BASH but Busybox.

Edit:
Works just fine, typo.

sundialsvcs 11-17-2011 08:16 PM

Uhh... dare I say that "maybe you're using the wrong (non-)language?" :doh:

No, no, I'm utterly and completely serious!! (And I absolutely, positively, mean nothing "personal" in what I'm saying here, so please put that flame-torch away before ya hurt someone with it.)

Bash is a shell, nothing more and nothing less. Yes, it is true that it does have a modicum of "scripting capability," but the only gentleman who ever felt that a shell was a proper place to put a complete programming language was Dr. David Korn.

I respectfully disagree with Dr. Korn.

The Linux/Unix programming environments give you "an embarrassment of riches" with respect to programming and so-called "scripting" languages that were specifically intended for the development of very sophisticated programs ... as well as the development of more utilitarian scripts. All of them are available to you free-of-charge: Perl, Python, Ruby, Prolog, PHP, Haskell, Erlang, aye, the list is endless. And all of them can be used to construct "a command-line program" through the magic of the so-called "shebang" ... #! ... appearing as the first line of your favorite script.

All shells will look at the first line of the file for a "shebang," and if they find it they will invoke the specified language-processor program to carry out the script ... and the user will be none the wiser.

Thus, you are liberated from your concerns of "how to make a Bash script do" ... what a Bash script was never intended to do. (And Bash is likewise liberated from any expectations of having to do what it was never intended to do.)

"HTH." (And let me reinforce, in closing, that I am not poking fun at you. When "the proverbial little light-bulb came on" about this for me, it was a huge lateral shift in my thinking. I suddenly realized why a couple of Bell Labs researchers in the 1970's had completely blown MULTICS out of the water using nothing more than a PDP-7 and a different way of thinking about everything.)

Juako 11-17-2011 08:37 PM

While I generally agree with your post, in this case the shell is more than equipped to make a simple substring test...just sayin'.

A couple exceptions I see to the rule of not trying to do full-blown programming in shell: when you are constrained to small systems where pretty much that's your only tool, the "shell gymnastics" case: when you want to learn intricacies of the language or just get some training to gain fluidity. And finally the "for the lulz/just because" case, which is not the less important: sometimes it's just fulfilling to see a video game made in shell (or sed! like sedtris).

At the end, I'd like some mix between an interactive shell and a interpreter for a fullblown lang to come up, mixing the best of two worlds: simple when you want simple, and powerful when you want powerful.

To the OP:
Quote:

My background is C so I came up with strstr(). I've checked a number of websites and it seems like mission impossible to do some sort of simple string compare in BASH
Perhaps you didn't check the right ones?

http://tldp.org/LDP/abs/html
http://wiki.bash-hackers.org/start
http://mywiki.wooledge.org/BashFAQ
http://www.commandlinefu.com

nedro 02-05-2012 02:06 PM

Shells are more than equipped to make a simple substring test, MUCH MORE
 
I completely agree with Juako on this ‘the shell is more than equipped to make a simple substring test”, but I go a bit further. For my work on a SUN Station, we were doing software builds utilizing MAKE, but to verify that everything we expected to be in the build was really there, we would then Extract all the files into another directory. I thought DIFF looked like it would work, but it was greatly lacking when a file was missing from one directory or the other, so I wrote a C-Shell Script, utilizing DIFF, to compare file by file and report the result in a Log. I later translated this script into the Korn Shell, and then into the BASH Shell Scripting. All worked identically and perfectly.

The “WHICH” Command, as defined by Wikipedia:
which is a Unix command used to identify the location of executables.
The command takes one or more arguments; for each of these arguments, it prints to stdout the full path of the executable that would have been executed if this argument had been entered into the shell. It does this by searching for an executable or script in the directories listed in the environment variable PATH.

I wrote MY OWN Version of WHICH when I found it had GREAT Limitations of running in a New Process (thus ignoring anything defined in the current process), and ONLY in a C-Shell. I once again have three version of my script, C-Shell, Korn, and BASH, BUT My version Doesn’t Just report the FIRST occurrence of an Executable, Built-in, or Alias, it reports ALL Occurrences of the specified command , and reports all the Functions for the Korn and BASH Shells as well, and in the order in which they would be executed.

This was achieved with the Lowly Little Script Languages


All times are GMT -5. The time now is 10:56 PM.