I have a few locations that need the WiFi to be checked daily. Currently when I run my script this is the outcome I get.

The first name corresponds to the first MAC, the first IP and so on. How may I go about re-arranging this file with grep, awk or sed?

Name                : WiFi 1
Name                : WiFi 2
Name                : WiFi 3
Name                : WiFi 4
Name                : WiFi 5
Name                : WiFi 6
Name                : WiFi 7
MAC                 : aa:aa:aa:aa:aa:aa
MAC                 : bb:bb:bb:bb:bb:bb
MAC                 : cc:cc:cc:cc:cc:cc
MAC                 : dd:dd:dd:dd:dd:dd
MAC                 : ee:ee:ee:ee:ee:ee
MAC                 : ff:ff:ff:ff:ff:ff
MAC                 : gg:gg:gg:gg:gg:gg
IP                  : 10.0.1.0
IP                  : 10.0.1.1
IP                  : 10.0.1.2
IP                  : 10.0.1.3
IP                  : 10.0.1.4
IP                  : 10.0.1.5
IP                  : 10.0.1.6
Status              : Operational
Status              : Operational
Status              : Operational
Status              : Operational
Status              : Operational
Status              : Operational
Status              : Operational
Interface           : X2
Interface           : X2
Interface           : X2
Interface           : X2
Interface           : X2
Interface           : X2
Interface           : X2

I'd like them all to output as shown below

Name                : WiFi 1
MAC                 : aa:aa:aa:aa:aa:aa
IP                  : 10.0.1.0
Status              : Operational
Interface           : X2
share|improve this question
1  
In which way would you want to rearrange it? What is the expected output? What have you tried so far? – Kusalananda 11 hours ago
    
Why is the first name "obviously " associated to the first MAC & etc? – Jeff Schaller 11 hours ago
    
I updated the post to show the way i'd like it to output. I've tried a using grep and piping it to tail but if I have a site with 3 access points or 12 access points it doesn't work. I also tried to use awk but I don't really know how to use regex. – ampadmos 11 hours ago
6  
Perhaps it makes more sense to adjust how the script outputs, to achieve your desired results. – Timothy Martin 11 hours ago
up vote 3 down vote accepted

This script will do the job, if I understand the requirements correctly:

#!/usr/bin/zsh

grep Name $1 > /tmp/wifinames
grep MAC $1 > /tmp/wifiMAC
# ...
# add lines for other fields here, you can store the names of files 
# in an array like ['file1', file2',..], and run a for loop printing the nth line inside the
# while loop below


i=1
n=`wc -l /tmp/wifinames|awk '{print $1}'`
# maybe you should run some tests to check if all the files
# produced by grep have equal number of entries 


while [[ $i -le $n ]]; do
    # prints nth line
    sed "${i}q;d" /tmp/wifinames
    sed "${i}q;d" /tmp/wifiMAC
    # ...
    (( i = $i + 1 ))
done

this answer is not very efficient, you see it's O(n^2) complexity, because it'll go through i lines every time to print ith line, one fallback of linux shell, but what the heck, if I'm correct the input size for this script will be no more than 10 connections, plus these shell provide solutions faster than fast food. But I would love to hear if someone has a more efficient solution.

share|improve this answer

Self-counting version, season to taste:

awk '    $1!=last {n=0;last=$1}
         {++n;gaggle[n]=gaggle[n]"\n"$0}
         END { for (k in gaggle) print gaggle[k] }
'
share|improve this answer
    
Makes the first AP come out last, but I don't know if it matters. – Kusalananda 9 hours ago
    
@don_crissti Ah, with mawk and gawk it does indeed work fine. I was testing with BSD awk (nawk?) when I commented... – Kusalananda 9 hours ago
2  
awk doesn't guarantee sequence on in results, if it matters you could for (k=1;k<=n;++k) or track the count some other way. – jthill 8 hours ago

For seven APs, with GNU sed and bash/ksh:

for (( i = 1; i <= 7; ++i )); do
  sed -n "$i~7p" data
  echo
done

With the provided information in data, this yields

Name                : WiFi 1
MAC                 : aa:aa:aa:aa:aa:aa
IP                  : 10.0.1.0
Status              : Operational
Interface           : X2

Name                : WiFi 2
MAC                 : bb:bb:bb:bb:bb:bb
IP                  : 10.0.1.1
Status              : Operational
Interface           : X2

Name                : WiFi 3
MAC                 : cc:cc:cc:cc:cc:cc
IP                  : 10.0.1.2
Status              : Operational
Interface           : X2

(etc.)

If we don't know how many APs there are, count the Name lines:

num="$( grep -c '^Name' data )"

for (( i = 1; i <= num; ++i )); do
  sed -n "$i~${num}p" data
  echo
done

The GNU sed-specific range syntax first~step will

Match every step'th line starting with line first.

according to the GNU sed manual.

share|improve this answer

Yet another way:

num=$(grep -c ^Name inputfile)
for((i=1; i <= num; i++)); do 
  for((j=1; j < num- 1; j++)); do 
    printf "%dp;" $((i + (j-1)*num)); 
  done; 
  printf "\n"; 
done | while read cmd; do sed -n "$cmd" inputfile; done
share|improve this answer
    
It wasn't as sneaky as I first thought it would be, but neat none the less ;-) You need $num in the printf too where you now have 7, though. – Kusalananda 10 hours ago
    
Ack, thanks @Kusalananda -- leftover from the initial hard coding – Jeff Schaller 10 hours ago

Here's another approach in GNU awk.

awk '{a[(NR-1)%7]=a[(NR-1)%7]$0RS}END{for(;i<7;){print a[i++]}}'

Name                : WiFi 1
MAC                 : aa:aa:aa:aa:aa:aa
IP                  : 10.0.1.0
Status              : Operational
Interface           : X2

Name                : WiFi 2
MAC                 : bb:bb:bb:bb:bb:bb
IP                  : 10.0.1.1
Status              : Operational
Interface           : X2
[etc]
share|improve this answer

Another approach, without awk or sed, cause why not:

split -a 1 -l 7 inputfile && paste -d '\n' x{a,b,c,d,e}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.