Versão de autocontagem, temporada a gosto:
awk ' $1!=last {n=0;last=$1}
{++n;gaggle[n]=gaggle[n]"\n"$0}
END { for (k in gaggle) print gaggle[k] }
'
Eu tenho alguns locais que precisam do Wi-Fi para serem verificados diariamente. Atualmente, quando executo meu script, esse é o resultado que obtenho.
O primeiro nome corresponde ao primeiro MAC, o primeiro IP e assim por diante. Como posso reorganizar esse arquivo com grep
, awk
ou 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
Gostaria que todos saíssem como mostrado abaixo
Name : WiFi 1
MAC : aa:aa:aa:aa:aa:aa
IP : 10.0.1.0
Status : Operational
Interface : X2
Por sete APs, com% GNUsed
e bash
/ ksh
:
for (( i = 1; i <= 7; ++i )); do
sed -n "$i~7p" data
echo
done
Com as informações fornecidas em data
, isso gera
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.)
Se não sabemos quantos APs existem, conte as Name
lines:
num="$( grep -c '^Name' data )"
for (( i = 1; i <= num; ++i )); do
sed -n "$i~${num}p" data
echo
done
A sintaxe do intervalo sed
do GNU first~step
será
Match every
step
'th line starting with linefirst
.
de acordo com o manual GNU sed
.
Mais uma forma:
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
Outra abordagem, sem awk
ou sed
, porque não:
split -a 1 -l 7 inputfile && paste -d '\n' x{a,b,c,d,e}
Aqui está outra abordagem em 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]
Esse script fará o trabalho se eu entender os requisitos corretamente:
#!/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
Tags grep awk sed text-formatting