I'm trying to parse the "parsable" ouput of the avahi-browse command for use in a shell script. e.g.
for i in $(avahi-browse -afkpt | awk -F';' '{print $4}') ; do <do something with $i> ; done
The output looks like:
;br.vlan150;IPv4;Sonos-7828CAC5D944\064Bedroom;_sonos._tcp;local
I am particularly interested in the value of the 4th field, which is a "service name".
With the -p|--parsable
flag, avahi-browse
escapes the "service name" values.
For example 7828CAC5D944\064Bedroom
, where \064
is a zero-padded decimal representation of the ASCII character '@'.
I just want 7828CAC5D944@Bedroom
so I can, for example, use it as an argument to another command.
I can't quite figure out how to do this inside the shell.
I tried using printf
, but that only seems to interpret octal escape sequences. e.g.:
# \064 is interpreted as 4
$ printf '%b\n' '7828CAC5D944\064Bedroom'
7828CAC5D9444Bedroom
How can I parse these values, converting any of the decimal escape sequences to their corresponding ASCII characters?
CodePudding user response:
Assumptions:
- there's a reason the
-p
flag cannot be removed (will removing-p
generate a@
instead of\064
?) - the 4th field is to be further processed by stripping off all text up to and including a hyphen (
-
) \064
is the only escaped decimal value we need to worry about (for now)
Since OP is already calling awk
to process the raw data I propose we do the rest of the processing in the same awk
call.
One awk
idea:
awk -F';' '
{ n=split($4,arr,"-") # split field #4 based on a hyphen delimiter
gsub(/\\064/,"@",arr[n]) # perform the string replacement in the last arr[] entry
print arr[n] # print the newly modified string
}'
# or as a one-liner:
awk -F';' '{n=split($4,arr,"-");gsub(/\\064/,"@",arr[n]);print arr[n]}'
Simulating the avahi-browse
call feeding into awk
:
echo ' ;br.vlan150;IPv4;Sonos-7828CAC5D944\064Bedroom;_sonos._tcp;local' |
awk -F';' '{n=split($4,arr,"-");gsub(/\\064/,"@",arr[n]);print arr[n]}'
This generates:
7828CAC5D944@Bedroom
And for the main piece of code I'd probably opt for a while
loop, especially if there's a chance the avahi-browse/awk
process could generate data with white space:
while read -r i
do
<do something with $i>
done < <(avahi-browse -afkpt | awk -F';' '{n=split($4,arr,"-");gsub(/\\064/,"@",arr[n]);print arr[n]}')
CodePudding user response:
Using perl
to do the conversion:
$ perl -pe 's/\\(\d )/chr $1/ge' <<<"7828CAC5D944\064Bedroom"
7828CAC5D944@Bedroom
As part of your larger script, completely replacing awk
:
while read -r i; do
# do something with i
done < <(avahi-browse -afkpt | perl -F';' -lane 'print $F[3] =~ s/\\(\d )/chr $1/ger')