AWKing or GREPing brackets [ ]? - awk

I've searched all over and couldn't find a solution.
How would I awk or grep the following:
$ mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration
[/dev/cdc-wdm0] IPv4 configuration available: 'address, gateway, dns'
IP [0]: '11.22.333.44/55'
Gateway: '14.13.198.4'
DNS [0]: '172.17.1.101'
DNS [1]: '172.17.1.102'
DNS [2]: '172.17.1.101'
DNS [3]: '172.17.1.102'
So that I end up with:
11.22.33.44/55
I've tried a bunch of different combinations with both grep and awk and couldn't find a solution.

Using cat file as I don't have mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration:
$ cat file | awk -F"'" '/IP \[/{print $2}'
11.22.333.44/55
$ cat file | awk -F"'" '/Gateway/{print $2}'
14.13.198.4
or maybe this is all you need if the output of that command always looks like the example you posted:
$ cat file | awk -v RS= -F"'" '{print $5}'
11.22.333.44/55
$ cat file | awk -v RS= -F"'" '{print $8}'
14.13.198.4

You can do this in a single awk:
mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration |
awk '$1 == "IP" {gsub(/\047/, "", $NF); print $NF}'
11.22.333.44/55

something like this:
grep '[0-9]' file_with_text | awk '{print $NF}
grep [0-9] only lines with numbers and pipe the output into awk.
The $NF will return the last element.
If you want only the line that has the /, just add it to grep [0-9]/.
Also, for a complete answer, you can pipe the output of the command into grep:
mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration | grep '[0-9]/' | awk '{print $NF}

I would harness tr for preprocessing and GNU AWK for processing, let file.txt content be
IP [0]: '11.22.333.44/55'
Gateway: '14.13.198.4'
DNS [0]: '172.17.1.101'
DNS [1]: '172.17.1.102'
DNS [2]: '172.17.1.101'
DNS [3]: '172.17.1.102'
then
cat file.txt | tr -d "'" | awk '/IP/{print $NF}'
output
11.22.333.44/55
Explanation: use tr to delete ' then awk to print last column ($NF) if row contain IP.
(tested in tr (GNU coreutils) 8.30 and GNU Awk 5.0.1)

Related

Running "ip | grep | awk" within a sed replacement

Problem Set (Raspberry Pi OS):
I have a file example.conf that contains a line IPv4addr=XXXXX. I am attempting to change this to the IP that is generated the in the command
ipTest=$(ip --brief a show | grep eth0 | awk '{ print $3 }')
I want to automate this file change during a script install.sh, the line I am attempting is:
IPtest=$(ip --brief a show | grep eth0 | awk '{ print $3 }')
sudo sed -e "/IPv4addr/s/[^=]*$/$IPtest/" example.conf
Returns error:
sed: -e expression #1, char 32: unknown option to `s'
A simple line in that code works, such as SimpleTest='Works'
Any thoughts? I am open to other solutions as well, however I am not an experienced linux user so I am using the tools I know to work with other problem sets.
$IPtest contains the / character; try something like this:
IPtest=$(ip --brief a show | grep eth0 | awk '{ print $3 }')
sudo sed -e '/IPv4addr/s#[^=]*$#'"$IPtest"'#' example.conf
You can shorten your variable and allow awk to do the job of grep at the same time
IPtest=$(ip --brief a s | awk '/eth0/{print $3}')
Using sed grouping and back referencing
sed -i.bak "s|\([^=]*.\).*|\1$IPtest|" example.conf

Assign variable to cut -f field

Using cut, I want to know how to use it as:
awk -v id=3 -v RS= -F '::' '($1==id) {print $3}' jenny | a=1 ;cut -d$'\n' -f$a
I want to use it in a loop where i is replaced with, e.g., -f 1...3
Input
0::chkconfig --list autofs::
autofs 0:off 1:off 2:on 3:on 4:on 5:on 6:off
1::grep "^PROMPT=" /etc/sysconfig/init::
PROMPT=yes
2::rpm -q prelink::
prelink-0.4.0-2.el5
3::if [ -z "$(grep -l "hard core" /etc/security/limits.conf /etc/security/limits.d/*)" ]; then echo "empty"; else echo -e "$(grep -l "hard core" /etc/security/limits.conf /etc/security/limits.d/*)"; fi::
/etc/security/limits.conf
/etc/security/limits.d/test
4::sysctl fs.suid_dumpable::
fs.suid_dumpable = 0
5::stat /etc/motd::
File: `/etc/motd'
Size: 17 Blocks: 16 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 10125343 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-04-09 07:56:19.000000000 +0500
Modify: 2019-03-30 19:22:13.000000000 +0500
Change: 2019-03-30 19:22:13.000000000 +0500
Expected Output
/etc/security/limits.conf
/etc/security/limits.d/test
As field 1 and field currently it's all coming in $3. I tried separating with newline in awk; it doesn't seem to catch.
To get your desired output from the given input, try:
$ awk '/^$/{f=0} f{print} /3::/{f=1}' file
/etc/security/limits.conf
/etc/security/limits.d/test
To get only one output line as selected with a variable i:
$ awk -v i=1 '/3::/{n=NR+i} n==NR' file
/etc/security/limits.conf
$ awk -v i=2 '/3::/{n=NR+i} n==NR' file
/etc/security/limits.d/test
The awk variable i can, of course, be set to the value of a shell variable i:
$ i=2
$ awk -v i="$i" '/3::/{n=NR+i} n==NR' file
/etc/security/limits.d/test
The stanza can also be selected from a variable:
$ i=2
$ k=3
$ awk -v i="$i" -v k="$k" -F:: '$1==k{n=NR+i} n==NR' file
/etc/security/limits.d/test
How it works:
-v i="$i" -v k="$k"
These options set awk variable i and k to the values of the shell variables $i and $k, respectively.
-F::
This sets the field separator to ::.
$1==k {n=NR+i}
If the first field of the current line equals the variable k, then set variable n to the current line number, NR, plus i.
n==NR
If the current line number, NR, is n, then print this line.
With sed:
$ id=3; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny
/etc/security/limits.conf
/etc/security/limits.d/test
Explanations:
Your shell will interpret the command and replace id by its value.
/^$id::/,/^$/{} the scope {} will be executed only between the lines that starts with the value of id followed by :: (/^$id::/) until an empty line (/^$/)
/^[[:blank:]]*\//p for the lines that start with some POSIX blank character class (e.g. space/tab) followed by / print the line. This will print your two paths.
To specify a line:
$ id=3; line=1; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | cut -d$'\n' -f"$line"
/etc/security/limits.conf
$ id=3; line=2; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | cut -d$'\n' -f"$line"
/etc/security/limits.d/test
$ id=3; line=1; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | sed -n "${line}p"
/etc/security/limits.conf
$ id=3; line=2; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | sed -n "${line}p"
/etc/security/limits.d/test
Assuming you want to build onto your previous question rather than coming up with a completely different approach
$ awk -v id=3 -v lineNr=1 -v RS= -F '::' '$1==id{ split($3,lines,/\n/); print lines[lineNr+1] }' file
/etc/security/limits.conf
$ awk -v id=3 -v lineNr=2 -v RS= -F '::' '$1==id{ split($3,lines,/\n/); print lines[lineNr+1] }' file
/etc/security/limits.d/test

awk for multiple pattern search & remove the first line from the output at the same time

I need to remove the first line of my output to be removed with awk. Below is the command and output has been displayed..
bash-3.2$ ldaplist -l hosts mylv104 | awk -F: '/cdsLocationDetail|.seemac.com|ipHostNumber/ {print $2}'
cn=mylv104+ipHostNumber=196.2.16.181,ou=hosts,ou=corp,ou=services,o=seemac.com
R3/C12/U21
mylv104.seemac.com
196.2.16.181
Though i got it with another awk with pipe but i don't want that..
bash-3.2$ ldaplist -l hosts mylv104 | awk -F: '/cdsLocationDetail|.seemac.com|ipHostNumber/ {print $2}' |awk 'NR>1'
R3/C12/U21
mylv104.seemac.com
196.2.16.181
You can set a flag when a line is matched, as shown below:
ldaplist -l hosts mylv104 | awk -F: '/cdsLocationDetail|.seemac.com|ipHostNumber/{if(!firstMatch){firstMatch=1;next;}print $2}'

How to print IP address using tcpdump and awk?

I used this command but I am unable to print multiple values before each '.'
This command is only printing the 192 of 192.168.113.2. I want to print the rest as well in the same line.
sudo tcpdump -i 2 -c 20 -n | awk -F '>' '{print $2}' | awk -F ':' '{print $1}' | awk -F '.' '{print $1}'
Please help.
sudo tcpdump -i 2 -c 20 -n | awk -F '>' '/>/{sub(".[^.]*:.*$", "", $2 ); print $2}'

Linux Grep or Awk to find strings and store into array

I would like to print the string in the following pattern. And I would like to store it in a array. Please help me, I need O/p as follows
test11
orcl
My commands/Tries
egrep -i ":Y|:N" /etc/oratab | cut -d":" -f1 | grep -v "\#" | grep -v "\*" | tr -d '\n' | sed 's/ /\n/g' | awk '{print $1}'
Above commands O/p:
test11orcl
Contents of Oratab will be as follows,
[oracle#rhel6112 scripts]$ cat/etc/oratab
#
# This file is used by ORACLE utilities. It is created by root.sh
# and updated by the Database Configuration Assistant when creating
# a database.
# A colon, ':', is used as the field terminator. A new line terminates
# the entry. Lines beginning with a pound sign, '#', are comments.
#
# Entries are of the form:
# $ORACLE_SID:$ORACLE_HOME:<N|Y>:
#
# Multiple entries with the same $ORACLE_SID are not allowed.
#
#
test11:/u01/app/oracle/product/11.2.0/dbhome_1:N
orcl:/u01/app/oracle/product/10.2.0/db_1:N
End of Cat Output
From the above file am trying to extract the STRING before the :/
As a start, try this:
$ cat input.txt
test11:/u01/app/oracle/product/11.2.0/dbhome_1:N
orcl:/u01/app/oracle/product/10.2.0/db_1:N
$ awk -F: '{print $1}' input.txt
test11
orcl
update
Using bash:
#!/bin/bash
ARRAY=()
while read -r line
do
[[ "$line" = \#* ]] && continue
data=$(awk -F: '{print $1}' <<< $line)
ARRAY+=($data)
done < input.txt
for i in "${ARRAY[#]}"
do
echo "$i"
done
In action:
$ ./db.sh
test11
orcl
You could use sed also,
sed -r 's/^([^:]*):.*$/\1/g' file
Example:
$ cat cc
test11:/u01/app/oracle/product/11.2.0/dbhome_1:N
orcl:/u01/app/oracle/product/10.2.0/db_1:N
$ sed -r 's/^([^:]*):.*$/\1/g' cc
test11
orcl
OR
$ sed -nr 's/^(.*):\/.*$/\1/p' file
test11
orcl