Ricardo
Ricardo

Reputation: 11

Parsing out numbers from a string - BASH script

I have a text file with the following contents:

QAM Mode : QAM-16  
QAM Annex : Annex A  
Frequency : 0 Hz  
IF Frequency : 0 Hz  
Fast Acquisition  : 0  
Receiver Mode  : cable  
QAM Lock : 1  
FEC Lock : 1  
Output PLL Lock : 0  
Spectrum Inverted : 0  
Symbol Rate : -1  
Symbol Rate Error : 0  
IF AGC Level (in units of 1/10 percent) : 260  
Tuner AGC Level (in units of 1/10 percent) : 1000  
Internal AGC Level (in units of 1/10 percent) : 0  
SNR Estimate (in 1/100 dB) : 2260  
**FEC Corrected Block Count (Since last tune or reset) : 36472114  
FEC Uncorrected Block Count (Since last tune or reset) : 0  
FEC Clean Block Count (Since last tune or reset) : 0**  
Cumulative Reacquisition Count : 0  
Uncorrected Error Bits Output From Viterbi (Since last tune or reset) : 0  
Total Number Of Bits Output from Viterbi (Since last tune or reset) : 0  
viterbi bit error rate (in 1/2147483648 th units) : 0  
Carrier Frequency Offset (in 1/1000 Hz) : -2668000  
Carrier Phase Offset (in 1/1000 Hz) : 0  
**Good Block Count (Reset on read) : -91366870**  
**BER Raw Count (Reset on read) : 0**  
DS Channel Power (in 10's of dBmV units ) : -760  
Channel Main Tap Coefficient : 11846  
Channel Equalizer Gain Value in dBm : 9  
**Post Rs BER : 2147483648  
Post Rs BER Elapsed Time (in Seconds) : 0**  
Interleave Depth : 1  

I need to parse the numbers from the bolded lines using a bash script but I haven't been able to do this with the command set I have available. This is my first time every using BASH scripts and the searches I've found that could help used some grep, sed, and cut options that weren't available. The options I have are listed below:

grep

Usage: grep [-ihHnqvs] PATTERN [FILEs...]  
Search for PATTERN in each FILE or standard input.  
Options:  
        -H      prefix output lines with filename where match was found  
        -h      suppress the prefixing filename on output  
        -i      ignore case distinctions  
        -l      list names of files that match  
        -n      print line number with output lines  
        -q      be quiet. Returns 0 if result was found, 1 otherwise  
        -v      select non-matching lines  
        -s      suppress file open/read error messages  

sed

BusyBox v1.00-rc3 (00:00) multi-call binary  
Usage: sed [-efinr] pattern [files...]  
Options:  
        -e script       add the script to the commands to be executed  
        -f scriptfile   add script-file contents to the  
                        commands to be executed  
        -i              edit files in-place  
        -n              suppress automatic printing of pattern space  
        -r              use extended regular expression syntax  
If no -e or -f is given, the first non-option argument is taken as the sed  
script to interpret. All remaining arguments are names of input files; if no  
input files are specified, then the standard input is read.  Source files  
will not be modified unless -i option is given.  

awk

BusyBox v1.00-rc3 (00:00) multi-call binary  
Usage: awk [OPTION]... [program-text] [FILE ...]  
Options:  
        -v var=val              assign value 'val' to variable 'var'  
        -F sep                  use 'sep' as field separator  
        -f progname             read program source from file 'progname'  

Can someone please help me with this? Thanks!

Upvotes: 1

Views: 2596

Answers (4)

Digital Trauma
Digital Trauma

Reputation: 15986

In addition, you can do this with a pure bash one-liner, no awk, sed, grep, or other helpers:

$  { while read line; do if [[ $line =~ "Post Rs BER : (.*)$" ]]; then echo ${BASH_REMATCH[1]}; fi; done; } < data.txt 
2147483648
$

or

$ cat data.txt | { while read line; do if [[ $line =~ "Post Rs BER : (.*)$" ]]; then echo ${BASH_REMATCH[1]}; fi; done; }
2147483648
$ 

Upvotes: 0

Digital Trauma
Digital Trauma

Reputation: 15986

If you have the right grep, you can do this with grep alone, using a regex look-ahead:

$ /bin/grep -Po "(?<=Post Rs BER : )(.+)" data.txt 
2147483648
$

I got the inspiration for this here

Upvotes: 0

Dennis Williamson
Dennis Williamson

Reputation: 359875

AWK can do that for you:

awk '/^(FEC.*Block|Good Block|BER|Post)/{print $NF}' textfile

Upvotes: 4

Erik
Erik

Reputation: 91260

grep -e "^FEC " -e "^Good Block" -e "BER" file.txt | awk '{print $NF}'

grep: Match lines that: start with FEC or start with Good Block or contains BER

awk: Print the last space-separated field in each line

Upvotes: 0

Related Questions