Home > Software engineering >  Bash, pass multiple values in one argument
Bash, pass multiple values in one argument

Time:08-22

I want to assume that the user of the following script sample4.sh knows nothing about Bash. The input file is posted here samples.bin

hexdump -v -e '8/1 "x " "\n"' samples.bin | mawk '
    BEGIN {
        printf "\t\tCh0    Ch1    Ch2    Ch3\n"        # print the header line
    }
    {
        printf("Sample %d:", NR - 1)                            # print the sample number
        printf(substr("        ", 1, 8 - length(NR - 1)))       # adjust the length of the spaces
        for (i = 1; i <= NF; i =2) {                            # print every two nibbles
            j = i   1
            printf("0x%s%s%s", $i, $j, j == NF ? ORS : OFS)
        }
    }
'

The deprecated output of sample4.sh (with no arguments) looks like:

                Ch0    Ch1    Ch2    Ch3
Sample 0:       0x1a03 0x1a03 0x4a03 0x5703
Sample 1:       0x4b03 0x4403 0x1e03 0x0904
Sample 2:       0x1003 0x1903 0x4003 0xae03
Sample 3:       0x1e03 0x2603 0x3303 0xad03
Sample 4:       0x1003 0x8403 0x4303 0x6203
Sample 5:       0xe003 0x1603 0x3403 0xc403
Sample 6:       0xf802 0x3b03 0x5303 0x6103
Sample 7:       0x1003 0x1503 0x4203 0x5803
Sample 8:       0x2303 0x1f03 0x5703 0x6203
Sample 9:       0x1703 0x7303 0x3103 0x3303
Sample 10:      0x1403 0xff02 0x3003 0x5103
Sample 11:      0x5f03 0x4203 0x4703 0x7e03
Sample 12:      0xba03 0x2603 0x3503 0xa003
Sample 13:      0x0803 0x3303 0x3603 0xc803
Sample 14:      0x0c03 0x3803 0x9703 0x4403
Sample 15:      0x0603 0x3503 0x4603 0x3103
Sample 16:      0x5003 0x3503 0x7f03 0x7f03
Sample 17:      0x1b03 0x4b03 0x4203 0xfb03
Sample 18:      0x1403 0x7304 0x2e03 0x4803
Sample 19:      0x0903 0x4a03 0x7103 0x5103

I want to allow the user to pass multiple values for $1 and $2, i.e..,

Note: Samples start at 0, so you can't go by line numbers.

Return samples 0 through 15, channels 0 through 3 expected output:

./sample4.sh -s 0-15 -c 0-3
                Ch0    Ch1    Ch2    Ch3
Sample 0:       0x1a03 0x1a03 0x4a03 0x5703
Sample 1:       0x4b03 0x4403 0x1e03 0x0904
Sample 2:       0x1003 0x1903 0x4003 0xae03
Sample 3:       0x1e03 0x2603 0x3303 0xad03
Sample 4:       0x1003 0x8403 0x4303 0x6203
Sample 5:       0xe003 0x1603 0x3403 0xc403
Sample 6:       0xf802 0x3b03 0x5303 0x6103
Sample 7:       0x1003 0x1503 0x4203 0x5803
Sample 8:       0x2303 0x1f03 0x5703 0x6203
Sample 9:       0x1703 0x7303 0x3103 0x3303
Sample 10:      0x1403 0xff02 0x3003 0x5103
Sample 11:      0x5f03 0x4203 0x4703 0x7e03
Sample 12:      0xba03 0x2603 0x3503 0xa003
Sample 13:      0x0803 0x3303 0x3603 0xc803
Sample 14:      0x0c03 0x3803 0x9703 0x4403
Sample 15:      0x0603 0x3503 0x4603 0x3103

Return samples 4 through 8 and channels 2 and 3 expected output:

./sample4.sh -s 4-8 -c 2-3
                Ch2    Ch3
Sample 4:       0x4303 0x6203
Sample 5:       0x3403 0xc403
Sample 6:       0x5303 0x6103
Sample 7:       0x4203 0x5803
Sample 8:       0x5703 0x6203

Return samples 0 through 9, channels 0 and 3 expected output:

./sample4.sh -s 0-9 -c 0,3
                Ch0    Ch3
Sample 0:       0x1a03 0x5703
Sample 1:       0x4b03 0x0904
Sample 2:       0x1003 0xae03
Sample 3:       0x1e03 0xad03
Sample 4:       0x1003 0x6203
Sample 5:       0xe003 0xc403
Sample 6:       0xf802 0x6103
Sample 7:       0x1003 0x5803
Sample 8:       0x2303 0x6203
Sample 9:       0x1703 0x3303

Return nonconsecutive samples with various channels expected output:

./sample4.sh -s 0,5,8 -c 0-3
                Ch0    Ch1    Ch2    Ch3
Sample 0:       0x1a03 0x1a03 0x4a03 0x5703
Sample 5:       0xe003 0x1603 0x3403 0xc403
Sample 8:       0x2303 0x1f03 0x5703 0x6203

Return total number of samples expected output:

./sample4.sh -t
Total Sample Count: 374371

And if you run the script with no arguments, the default is to return all samples with all channels. If you run with script specifying samples only and not channels, then you'll get the specified samples with all channels. If you run the script specifying channels only, then you get all samples with only the specified channels.

CodePudding user response:

Your "question" is actually 2 separate questions:

  1. How do I pass options passed to a shell script through to an awk script, and
  2. How to I make my awk script only print specific values based on strings passed in.

Here's the answer to the first question, i.e. get a shell script to take arguments and pass them through to an awk script (and I added tracing print statements so you can see the values):

$ cat sample4.sh
#!/usr/bin/env bash

while getopts ':c:s:t' opt; do
    case $opt in
        s) samps="$OPTARG" ;;
        c) chans="$OPTARG" ;;
        t) totReq=1 ;;
        *) printf 'Unrecognized option "%s"\n' "$opt" >&2
    esac
done
shift $(( OPTIND - 1 ))

printf 'samps="%s"\n' "$samps" >&2
printf 'chans="%s"\n' "$chans" >&2
printf 'totreq="%d"\n' "$totReq" >&2

hexdump -v -e '8/1 "x " "\n"' samples.bin |
awk -v samps="$samps" -v chans="$chans" -v totReq="$totReq" '
    BEGIN {
        printf "\t\tCh0    Ch1    Ch2    Ch3\n"        # print the header line
    }
    {
        printf("Sample %d:", NR - 1)                            # print the sample number
        printf(substr("        ", 1, 8 - length(NR - 1)))       # adjust the length of the spaces
        for (i = 1; i <= NF; i =2) {                            # print every two nibbles
            j = i   1
            printf("0x%s%s%s", $i, $j, j == NF ? ORS : OFS)
        }
    }
'

I'll let you figure out the answer to the second question of what to do with them inside the awk script and then you can ask another question some other time if you get stuck.

  • Related