Add colons to MAC address with awk? - linux

Below you seen my real code, I suppose it can be simplified to
$ echo 123456789012 | awk '{print $1}'
123456789012
Question
How can I get awk to add colons, it outputs 12:34:56:78:90:12 instead?
grep -v '^#' $hosts | grep -E '[0-9A-F]{12}\b' | grep -v 000000000000 | awk '{
print "host "$5" {"
print " option host-name \""$5"\";"
print " hardware ethernet "$3";"
print " fixed-address "$1";"
print "}"
print ""
}' > /etc/dhcp/reservations.conf

another way
$ echo 123456789012 | fold -w2 | paste -sd:
12:34:56:78:90:12
here is a different gawk version
$ echo 123456789012 | awk -v FPAT='..' -v OFS=':' '{$1=$1}1'
12:34:56:78:90:12

One more:
echo 0123456789ab | awk '{gsub(/..\B/,"&:")}1'

another way is to make use of gawk's FIELDWIDTHS
awk -v FIELDWIDTHS='2 2 2 2 2 2' -v OFS=":" '1+($1=$1)'

Could you please try following.
echo 123456789012 | awk '{gsub(/../,"&:");sub(/:$/,"")} 1'

Related

Strip a part of string in linux

Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 is my string and the result I want is vm-1.0.3
What is the best way to do this
Below is what I tried
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | awk -F - {'print $1,$2'}
vm 1.0.3
I also tried
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | awk -F - {'print $1"-",$2'}
vm- 1.0.3
Here I do not need space in between
I tried using cut and I got the expected result
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | cut -c 1-8
vm-1.0.3
What is the best way to do the same?
Making assumptions from the 1 example you provided about what the general form of your input will be so it can handle that robustly, using any sed:
$ echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' |
sed 's/^[^-]*-[^-]*-[^_]*_\(.*\)-[^-]*$/\1/'
vm-1.0.3
or any awk:
$ echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' |
awk 'sub(/^[^-]+-[^-]+-[^_]+_/,"") && sub(/-[^-]+$/,"")'
vm-1.0.3
You don't need 2 calls to awk, but your syntax with the single quotes outside the curly's, including printing the hyphen:
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 |
awk -F_ '{print $2}' | awk -F- '{print $1 "-" $2}'
If your string has the same format, let the field separator be either - or _
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F"[-_]" '{print $4 "-" $5}'
Or split the second field on - and print the first 2 parts
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F_ '{
split($2,a,"-")
print a[1] "-" a[2]
}'
Or with gnu-awk a bit more specific match with a capture group:
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 |
awk 'match($0, /^Apps-[^_]*_(vm-[0-9]+\.[0-9]+\.[0-9]+)/, a) {print a[1]}'
Output
vm-1.0.3
This is the easiest I can think of:
echo "Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2" | cut -c 25-32
Obviously you need to be sure about the location of your characters. In top of that, you seem to be have two separators: '_' and '-', while both characters also are part of the name of your entry.
echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' | sed -E 's/^.*_vm-([0-9]+).([0-9]+).([0-9]+)-.*/vm-\1.\2.\3/'

Using awk to split string with \n followed by ' and ,

If given the string '1234␤',56789, how can I use awk to split by the sequence ␤',? Here ␤ represents a literal newline character.
Right now I have,
echo $LINE | awk -F'\\\\n',' '{ print $1}'
The split doesn't happen with this. Any advice?
Try to print all fields using the value of -F
echo "1234\n',56789," | awk -F "[',]+" -v ORS="" '{$1=$1}1'
line="1234\n',56789,"; echo "$line" | awk -F "[',]+" -v ORS="" '{$1=$1; print $0}'
Output
1234\n 56789
To print a specific field
echo "1234\n',56789," | awk -F "[',]+" -v ORS="" '{$1=$1; print $1}'
line="1234\n',56789,"; echo "$line" | awk -F "[',]+" -v ORS="" '{$1=$1; print $1}'
Output
1234\n

Awk: parse node names out of "40*r13n15:40*r10n61:40*r11n18:40*r09n15"

I have a linux script for selecting the node.
For example:
4
40*r13n15:40*r10n61:40*r11n18:40*r09n15
The correct result should be:
r13n15
r10n61
r11n18
r09n15
My linux script content is like:
hostNum=`bjobs -X -o "nexec_host" $1 | grep -v NEXEC`
hostSer=`bjobs -X -o "exec_host" $1 | grep -v EXEC`
echo $hostNum
echo $hostSer
for i in `seq 1 $hostNum`
do
echo $hostSer | awk -F ':' '{print '$i'}' | awk -F '*' '{print $2}'
done
But unlucky, I got nothing about node information.
I have tried:
echo $hostSer | awk -F ':' '{print "'$i'"}' | awk -F '*' '{print $2}'
and
echo $hostSer | awk -F ':' '{print '"$i"'}' | awk -F '*' '{print $2}'
But there are wrong. Who can give me a help?
One more awk:
$ echo "$variable" | awk 'NR%2==0' RS='[*:\n]'
r13n15
r10n61
r11n18
r09n15
By setting the record separtor(RS) to *:\n , the string is broken into individual tokens, after which you can just print every 2nd line(NR%2==0).
You can use multiple separators in awk. Please try below:
h='40*r13n15:40*r10n61:40*r11n18:40*r09n15'
echo "$h"| awk -F '[:*]' '{ for (i=2;i<=NF;i+=2) print $i }'
**edited to make it generic based on the comment from RavinderSingh13.

Getting error while running script to find disk space

I am running below script:-
#!/bin/bash
threshold="20"
i=2
result=`df -kh |grep -v “Filesystem” | awk ‘{ print $5 }’ | sed ‘s/%//g’`
for percent in $result; do
if ((percent > threshold))
then
partition=`df -kh | head -$i | tail -1| awk ‘{print $1}’`
echo “$partition at $(hostname -f) is ${percent}% full”
fi
let i=$i+1
done
But I get the following error:
awk: ‘{
awk: ^ invalid char '▒' in expression
sed: -e expression #1, char 1: unknown command: `▒'
Please help me to resolve this.
What awk does not work? (your script does work fine on my Ubuntu)
This line:
result=`df -kh |grep -v "Filesystem" | awk '{ print $5 }' | sed 's/%//g'`
could be changed to:
result=$(df -kh | awk '!/Filesystem/ {print $5+0}')
Avoid using old and outdated backtics if parentheses works like this: var=$(code...)
This:
partition=`df -kh | head -$i | tail -1| awk '{print $1}'`
could be changed to:
partition=$(df -kh | awk -v line="$i" 'NR==line {print $1}')
This
let i=$i+1
could be change to:
((i++))
This would then give some like this:
#!/bin/bash
threshold="20"
i=2
result=$(df -kh | awk '!/Filesystem/ {print $5+0}')
for percent in $result; do
if ((percent > threshold))
then
partition=$(df -kh | awk -v line="$i" 'NR==line {print $1}')
echo "$partition at $(hostname -f) is ${percent}% full"
fi
((i++))
done
You're using ‘ for a single quote not '. Try re-encoding your file with an editor.
You got the answer to your syntax error, now re-write the whole script as just:
#!/bin/bash
df -kh |
awk -v t=20 -v h="$(hostname -f)" '(NR>1)&&($5+0>t){printf "%s at %s is %s full\n",$1,h,$5}'

Using awk to modify output

I have a command that is giving me the output:
/home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08 counted-file.xml.20131003-083611
I need the output to be:
ea66574ff0daad6d0406f67e4571ee08 counted-file.xml
The closest I got was:
$ echo /home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08 counted-file.xml.20131003-083611 | awk '{ printf "%s", $1 }; END { printf "\n" }'
/home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08
I'm not familiar with awk but I believe this is the command I want to use, any one have any ideas?
Or just a sed oneliner:
echo /home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08 counted-file.xml.20131003-083611 \
| sed -E 's/.*:(.*\.xml).*/\1/'
$ echo "/home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08 counted-file.xml.20131003-083611" |
cut -d: -f2 |
cut -d. -f1-2
ea66574ff0daad6d0406f67e4571ee08 counted-file.xml
Note that this relies on the dot . being present as in counted-file.xml.
$ awk -F[:.] -v OFS="." '{print $2,$3}' <<< "/home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08 counted-file.xml.20131003-083611"
ea66574ff0daad6d0406f67e4571ee08 counted-file.xml
not sure if this is ok for you:
sed 's/^.*:\(.*\)\.[^.]*$/\1/'
with your example:
kent$ echo "/home/konnor/md5sums:ea66574ff0daad6d0406f67e4571ee08 counted-file.xml.20131003-083611"|sed 's/^.*:\(.*\)\.[^.]*$/\1/'
ea66574ff0daad6d0406f67e4571ee08 counted-file.xml
this grep line works too:
grep -Po ':\K.*(?=\..*?$)'

Resources