Results 1 to 9 of 9
I'm feeling my way with bash scripting.......
The first line of my file is:
prmslmsl, [61][1][1]
and I want to extract the first no in the square brackets.
Code:
head ...
- 05-29-2009 #1Just Joined!
- Join Date
- May 2009
- Location
- Christchurch, NZ
- Posts
- 9
Extracting numbers between square brackets
I'm feeling my way with bash scripting.......
The first line of my file is:
prmslmsl, [61][1][1]
and I want to extract the first no in the square brackets.
gives me the answer, but it's very ugly.Code:head -n 1 GrADS.out | cut -d\, -f 2 | cut -d\] -f 1 | cut -d\[ -f 2
Is there a better way?
- 05-29-2009 #2Linux User
- Join Date
- Aug 2006
- Posts
- 458
if you have Python
awkCode:# python -c "first=open('file').readline();print first.split('[')[1][:-1]" 61
Code:awk -F"[" 'NR==1{sub("]","",$2);print $2}' file
- 05-29-2009 #3Just Joined!
- Join Date
- May 2009
- Location
- Oregon
- Posts
- 51
Depends on what "neat" is... using bash alone, I would do:
x=`head -n 1 GrADS.out`; x=${x#*[}; x=${x%%]*}; echo $x
Or, there is always sed --- available on just about all UNIX's.
Assuming there are no numbers before the first one, you can do:
head -n 1 GrADS.out | sed -ne "s%[^0-9]*\([0-9]*\).*%\1%p"
What's your preference?
- 05-29-2009 #4Linux User
- Join Date
- Aug 2006
- Posts
- 458
- 05-29-2009 #5Just Joined!
- Join Date
- May 2009
- Location
- Oregon
- Posts
- 51
aye, I wasn't specific -- I meant matching by bash alone....

And you see a workaround .... too.
or how about....
read -d ] x < GrADS.out; echo ${x#*[}
OOOOHHHHH.... or, do an
IFS="[]"; read -a x < GrADS.out; echo ${x[1]}
(could be executed in a subshell to save saving IFS and restoring... recurse.. curse...
....
Too bad sed doesn't allow positive matches .... it would make it so much more readable.

Oh, and since I cant sleep -- & my thread question isn't getting answers -- how about one that avoids your solution (read) but is more FLEXIBLE!!! USING TRULY ONLY BaSh!!!
(Pick a line, any line.... !1 = line 1, !2=line 2, etc....
x=( `bash -c 'history -cr GrADS.out; history -p "!1:gs/[/ /:gs/]//"' )
echo ${x[1]}
oddly, bash -c is required, as merely executing in a subshell does NOT reset the current history line to 0 -- a parenthetical inside the `( history -cr ... )` inherits the present history line number.
Unfortunately, I don't see a way to reset BASH's notion of the present history line number without calling bash, directly.... so, it is slower than a mere fork() -- challenge Q: does anyone know how to make that work without the bash -c ??? :shrug:Last edited by andrewr; 05-29-2009 at 09:44 AM. Reason: add a perverted way....
- 05-29-2009 #6Just Joined!
- Join Date
- May 2009
- Location
- Christchurch, NZ
- Posts
- 9
Thanks you blokes.
For me, the neatest is:
read -d ] x < GrADS.out; echo ${x#*[}
Now, I'm off to find out how it works exactly...............
- 05-29-2009 #7Just Joined!
- Join Date
- May 2009
- Location
- Christchurch, NZ
- Posts
- 9
I'm trying to understand this:
read -d ] x < GrADS.out; echo ${x#*[}
OK, I understand this bit:
read -d ] x < GrADS.out | echo $x
It gives:
prmslmsl, [61
First of all, why do we use ;, not | for the next bit? Either seems to work OK.
And I guess ${x#*[} means retain all the characters after the [
Where could I learn this stuff?
- 05-29-2009 #8Just Joined!
- Join Date
- May 2009
- Location
- Oregon
- Posts
- 51
Actually, I didn't use | between the commands because echo does not use std input.
the semicolon ; simply means the same as an enter button. It allows multiple unrelated/unpiped commands on one line.
You can get away with | because echo ignores the standard input and isn't confused by it.
I like your use of | better, and wish I had thought of that twisted thinking for 1 reason only -- BASH has bugs in job control (see the end of the man file -- under BUGS). Type: man bash
the | would prevent that problem .... hmmm.... neat.
for non-bug learning; With the manual up type:
/Parameter Expansion
followed by enter.
That will search for the section explaining how to remove parts of variables.
Actually, ${x#*[} is negative thinking only -- remove everything up to and including the [
Cheers.
P.S.
Sheeesh.... found another BASH BUG. Anyone know why this *DOESNT* work?
read -d ] < GrADS.out | echo ${REPLY#*[}
What is wrong with it, logically?
If nothing, could someone write to the bug list of whoever maintains BASH.
It has lots of quirks....Last edited by andrewr; 05-29-2009 at 10:23 AM. Reason: help, I'm editing and can't stooooooppppp.....
- 05-29-2009 #9Just Joined!
- Join Date
- May 2009
- Location
- Christchurch, NZ
- Posts
- 9
Thank you for your help, andrewr
${x#*[} seems like gobbledygook at first, but as I read the manual, it means take x and remove (#) everything (*) up to and including the [, which leaves 61.
Actually, I might revise my assessment of elegance and go for:
IFS="[]"; read -a x < GrADS.out; echo ${x[1]}
having just learned about IFS


Reply With Quote
