I want to split up a variable using awk by a colon, but only the last variable.
From this input:
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
I want the following output:
protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
This is my awk command now:
awk '/^ACCEPT/ {print "protocol=",$2, "source=",$4,"destination=",$5,"port=",$7}"
Which produces:
protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=dpt:22
But I want to get 22
out of $7
and not dpt:22
I've tried using awk's field separator, but I can figure out how to make it only apply to a single variable
As you can see, you can combine more than one delimiter in the AWK field separator to get specific information.
awk programming -Passing variable to awk for loop awk: BEGIN -------- <some code here> END{ ----------<some code here> for(N=0; N<H; N++) { for(M=5; M<D; M++) print "\t" D ""; } ----- } ... Discussion started by ctrld and has been viewed 2,402 times.
Specified multiple delimiters, one is : and other is ; . How awk parses the file? Its simple. First, it looks at the delimiters which is colon (:) and semi-colon (;). This means, while reading the line, as and when the delimiter : or ; is encountered, store the part read in $1. Continue further.
Simply, sum them up and store in $3, and print all the variables. OFS (output field separator) is used to specify the delimiter while printing the output. Note: If we do not use the OFS, awk will print the fields using the default output delimiter which is space.
There are various common types of delimiters that include: AWK RegEx Field Separator The AWK Field Separator (FS) is used to specify and control how AWK splits a record into various fields. Also, it can accept a single character of a regular expression.
Adding also | [ ]+ can be useful, but can make things tricky ... as there are often spaces before and after 'this', this will make 2 extra empty field appear in between the space (s) and 'this') Good news! awk field separator can be a regular expression. You just need to use -F"<separator1>|<separator2>|...":
Just tweak FS to include the :
$ echo 'ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22' |
awk '/^ACCEPT/{printf("protocol=%s source=%s destination=%s port=%s\n", $2,$4,$5,$8)}
' FS='[ :]*'
protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
You might need to include tabs, and do FS='[ :\t]*'
You can use a regex to define a custom field separators in awk
.
some_command | awk -F '[[:blank:]:]+' '/^ACCEPT/{
printf "protocol=%s source=%s destination=%s port=%s\n", $2, $4, $5, $NF}'
protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
-F '[[:blank:]:]+'
sets input field separator as one of white-space or colon.
slight modification in your awk command
$ awk '/^ACCEPT/ {gsub(/[^0-9]/,"",$7); print "protocol="$2, "source="$4,"destination="$5,"port="$7}' file
protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
gsub(/[^0-9]/,"",$7);
will nullify all non-digit characters in $7
Use the following awk approach:
awk '{ printf "protocol=%s source=%s destination=%s port=%s\n",$2,$4,$5,substr($7,5) }' file
But if the last field has dynamic prefix length you may apply gsub()
function to remove non-digit characters:
awk '{ gsub(/^[^0-9]+/,"",$7); printf "protocol=%s source=%s destination=%s port=%s\n",$2,$4,$5,$7 }' file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With