I am trying to substibute a variable from a stdout stream before writing it to file.
This is a tshark utility that is parsing some DNS stats and outputting to a file, it runs in the background
#tshark > $FILE 2>&1 &
The output looks something like this:
64.6.64.6 10.13.0.41 domain.com 3
What I am trying to do is substitute column 2 value with the regex output below:
grep 10.13.0.41 /etc/openvpn/openvpn-status.log |awk -F'[,:]' '{print $3}'
190.171.88.59
End result is $FILE will contain the line:
64.6.64.6 190.171.88.59 domain.com 3
CodePudding user response:
You can use sed
for this job:
cat ./filter.sh
#!/bin/bash
while IFS='$\n' read -r line; do
# Replace "echo 190.171.88.59" below with your commands to get the IP address
NEW_IP=$(echo 190.171.88.59)
printf "${line}\n" | sed "s/\ [0-9]\ \.[0-9]\ \.[0-9]\ \.[0-9]\ /\ ${NEW_IP}/"
done
$ cat tmp.txt
64.6.64.6 10.13.0.41 domain.com 3
64.6.64.6 1.1.1.1 domain.com 3
64.6.64.6 2.2.2.2 domain.com 3
64.6.64.6 3.3.3.3 domain.com 3
64.6.64.6 4.4.4.4 domain.com 3
64.6.64.6 1.2.3.4 domain.com 3
$ cat tmp.txt | ./filter.sh
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
So in the end you'll have something like:
tshark | ./filter.sh > $FILE 2>&1 &
If the output takes time to show up in $FILE
, you may have to check if tshark
is buffering when printing to the pipe (see the -l
parameter).
CodePudding user response:
Would you please try the following:
#!/bin/bash
ip=$(grep 10.13.0.41 /etc/openvpn/openvpn-status.log | awk -F'[,:]' '{print $3}')
tshark 2>&1 | awk -v ip="$ip" '{$2 = ip} 1' > "$FILE" &
ip=$( cmd )
assigns bash variableip
to the output of the command.- Awk option
-v ip="$ip"
sets the awk variableip
to the value of bash variable$ip
then the second field is replaced with it.
CodePudding user response:
maybe make it a single through pipeline
, plus one sub-shell
?
tshark 2>&1 | {m,g}awk '$(_ =_=_~_)=__' __="$(
{m,g}awk 'BEGIN { _*=(FS = "^[^,:]*[,:][^,:]*[,:]|[,:]. $" (OFS = ORS = _))
} _ { exit } _ = NF *= /[^0-9]?0?10[.]0?13[.]0 [.]0?41[^0-9]?/' \
\
'/etc/openvpn/openvpn-status.log' )" > "$FILE" &
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
64.6.64.6 190.171.88.59 domain.com 3
CodePudding user response:
You already found that awk
will do the job. You could simply pipe the output of tshark
into awk
,
(tshark 2>&1 | awk .... >$FILE) &