[Solved] Need a little help bash scripting

Hi ppl :slight_smile:

I need a little help for scripting a bash script for my LTE modem. It’s a Qualcomm modem which uses “qmicli” for sending certain commands to it.

Now that little tool for a data connection to establish needs a command + paramters that looks something like this:

qmicli --device=/dev/cdc-wdm0 --device-open-proxy --wds-start-network=ip-type=4,apn=data.tre.se --client-no-release-cid

Which then spits out something like this:

# [$DEVICE] Network started
#   Packet data handle: '12345678'
# [$DEVICE] Client ID not released:
#   Service: 'wds'
#       CID: '12'

What I need is the CID number, just the number, and store that in a variable or a file so I can call that when another command is later given to my script, like “stop” or “restart” for example.

I have no idea how to do that and if that is even possible in bash scripting, I know I probably have to regex it out of there but does bash (awk, sed and so on) allow only selecting a group of a regex like python does?

I only ever did some basic python regex so I’m very new to bash regex and variables and such.

I know of pipes and “>” and so on to write to file but I don’t know how that handle this.

Could someone tell me what to search for or help me out here otherwise please?

2 Likes

This command should get you what you need:

qmicli --device=/dev/cdc-wdm0 --device-open-proxy --wds-start-network=ip-type=4,apn=data.tre.se --client-no-release-cid | grep CID | awk '{print $3}' | tr -d "'"

grep CID will filter your modem output for just the line that contains the CID number. The awk '{print $3}' command will print the third field as it’s delimited by spaces and will output ‘12’ with the quotes. Finally, the tr -d "'" trims the quotes off the front and back of the string, leaving you with your number that you can redirect into your pidfile.

4 Likes

Hey thank you very much :smiley:
With that I can go further :slightly_smiling_face:
Sry I failed you in not removing the “#” so it needs to be “… awk ‘{print $2}’ …” :stuck_out_tongue_closed_eyes:
I so forgot about “grep” that it hurts :sweat_smile:

3 Likes

First final solution:

DEVICE=/dev/cdc-wdm0
CID_FILE=/tmp/qmi-cid

#Start data connection
qmicli --device=${DEVICE} --device-open-proxy --wds-start-network=ip-type=4,apn=${APN} --client-no-release-cid | grep CID | awk '{print $2}' | tr -d "'"  > ${CID_FILE}

cat /tmp/qmi-cid

20
#Disconnect data connection
qmicli --device=${DEVICE} --device-open-proxy --wds-stop-network=disable-autoconnect --client-cid=$(cat ${CID_FILE})

Those are just parts of my script and it works :smiley:

Thank you very much :slightly_smiling_face:

1 Like

Yo! This will be my golden chance to be “that guy” that crashes question threads telling you can replace all those pipes with a monstrous single unintelligible awk command!

Run your output through this aberration:

command | awk '/CID/ { gsub("'\''",""); print $3 }'

or if file just:

awk '/CID/ { gsub("'\''",""); print $3 }' /path/to/file

That’s it. No grep, tr or sed required.

I’m out!

1 Like

awk is one of those commands that I have somehow avoided for a long time. It’s been on my todo list to check out and get some basic proficiency with. I’ll probably kick myself afterwards for avoiding it for so long.

Same here. But its not as hard so you will probably google a few minutes and find a way to do what you want.

I think the biggest injustice with awk is that people think of it as an alternative to cut when in fact awk is a whole scripting language.

2 Likes

Ok but when you want to be “that guy” I would appreciate it very much if you could explain what it does step by step, since I’d like to learn :slight_smile:

2 Likes

I actually originally tried to use cut when I wrote my original solution above, with something along these lines:
cut -d ' ' -f 3 to set the delimiter (-d) to the space character and then get the third field (-f). The problem is that cut doesn’t group the separators together so you’ll get a bunch of empty fields when you have multiple separators like OP had originally. Is there a way cut could work here? I’ve found it much more useful when parsing fixed-width fields and things like that in the past.

Indeed. Probably because the variable number of whitespaces. To be honest I thought cut was smarter than that.

You can solve that by using xargs to trim the whitespaces:

$ grep CID golf.txt 
#       CID: '12'

$  grep CID golf.txt | xargs
# CID: 12

$ grep CID golf.txt | xargs | cut -d ' ' -f 3
12

Well its not like the previous solution didn’t worked. I’m being that guy precisely because the awk parse is way more confusing and seemingly ugly than the one using lots of pipes. It was meant to be a joke please don’t take it seriously.

2 Likes

Stop already- you’re casually throwing around all the linux commands that are black box mysteries to me. It’s like there is secret /usr/bin folder out there somewhere that I haven’t found.

edit - xargs and awk!

1 Like

Ooooh I just noticed xargs also did trimmed the single quotes. Good boy.

Oh ok, text doesn’t convey that very good when you don’t know the other person :upside_down_face:.

I still like to know what each segment does and what it means :slight_smile:

Awk is a text processing utility with lots of features. Its good at processing and manipulating text.

It will accept an input (command | awk ...) a file (awk ... filename) or you can also create a script with #/usr/bin/env awk.

I hope the text formatting doesn’t screw up:

awk '/CID/ { gsub("'\''",""); print $3 }'
     ^^^^    ^^^^^^^^^^^^^^^  ^^^^^^

1- search string
2- replace a single quote with nothing. "'" -> "". It is heavily escaped because ’ is an important operator for awk.
3- print third word in the string for each line processed

3 Likes