Using awk to print - macos

I currently have a script that will query the ownership of the partition.dumodule and have it print out the information:
echo *Checking Partition Permission* Hostname=$(hostname) LastChecked=$(date)
ls -l /applications/utilities/Disk\ Utility.app/contents/Plugins | grep Partition.dumodule | awk -v a=Username= -v b=DateModified= '{print a $3, b $6, $7, $8}'
It will print out like this:
*Checking Partition Permission* Hostname=<name> LastChecked=<date>
Username=<account> DateModified=<date>
Notice how the " Username= DateModified=" is on a separate line, this is the issue. I need it to all appear on the same line but I cannot figure out how to do this. I believe what needs to be done is have awk print out everything instead of running the "Hostname=$(hostname) LastChecked=$(date)" in the beginning, but how do I get awk to print out that information?
I have seen some forums and people say you can do something like this:
awk -v MYHOST=$(hostname) '{print MYHOST " " $4}'
However that gives me an error if you put the "MYHOST" variable to be printed. Any ideas?

Your echo statement is emitting a newline after it. Use -n to suppress the newline.
echo -n *Checking Partition Permission* Hostname=$(hostname) LastChecked=$(date)

Related

Why awk if conditional matching is wrong

In my project, I have two files.
The content userid is :
6534
4524
4522
6635
The content userpwinfo.txt is:
nsgg315_RJ:x:4520:100::/home-gg/users/nsgg315_RJ:/bin/bash
nsgg316_ZJY:x:4521:100::/home-gg/users/nsgg316_ZJY:/bin/bash
nsgg317_CPA:x:4522:100::/home-gg/users/nsgg317_CPA:/bin/bash
nsgg318_ZRL:x:4523:100::/home-gg/users/nsgg318_ZRL:/bin/bash
nsgg319_YYM:x:4524:100::/home-gg/users/nsgg319_YYM:/bin/bash
Now I want to print the username which id is in userid. I writed a bash shell like:
for i in $(cat userid)
do
#username=`awk -F: '{if($3=="$i") print $1}' /root/userpwinfo.txt`
#username=`awk -F: '$3=="$i" {print $1}' /root/userpwinfo.txt`
#username=`awk -F: '{if($3~/$i/) print $1}' /root/userpwinfo.txt`
username=`awk -F: '{if($3==$i) print $1}' /root/userpwinfo.txt`
echo $username
done
But unlucky, it shows nothing. The correct result should be:
nsgg319_YYM
nsgg317_CPA
I have tried in command line:
awk -F: '{if($3==4524) print $1}' /root/userpwinfo.txt
It is OK
Maybe if($3==$i) is wrong in shell, Who can help me?
Your $i is the shell variable, but it's inside the quotation mark ' so awk will try to interpret it instead of the shell.
Try this:
username=`awk -F: '{if($3=='$i') print $1}' /root/userpwinfo.txt`
Note that the $i is between ' marks, meaning it's outside of the block that will be interpreted by awk, meaning it should be interpreted by the shell.
Also note that if you have an empty line in the input file, your awk command would be if($3==) which is invalid and will yield an error.
I'd like to comment also that awk is meant to have a filter and an execution block. You shouldn't need to write an if inside a block, unless you want something unusual. Meaning, your command would be more appropriately written as:
username=`awk -F: '($3=='$i'){print $1}' /root/userpwinfo.txt`
Note that even this is not a very good solution, but you already have much to think about with only these changes. When you're more familiar with awk or getting more professional, come back and check the comments. ;)
If username is what you needed using the 2 files, you could try
$ cat userpwinfo.txt
nsgg315_RJ:x:4520:100::/home-gg/users/nsgg315_RJ:/bin/bash
nsgg316_ZJY:x:4521:100::/home-gg/users/nsgg316_ZJY:/bin/bash
nsgg317_CPA:x:4522:100::/home-gg/users/nsgg317_CPA:/bin/bash
nsgg318_ZRL:x:4523:100::/home-gg/users/nsgg318_ZRL:/bin/bash
nsgg319_YYM:x:4524:100::/home-gg/users/nsgg319_YYM:/bin/bash
$ cat userid.txt
6534
4524
4522
6635
$ awk -F":" ' { if( NR==FNR ) { a[$3]=$1; next } ; if(a[$1]) print a[$1] }' userpwinfo.txt userid.txt
nsgg319_YYM
nsgg317_CPA

Grep only 2 portions in a line

I have the following line. I can grep one part but struggling with also grepping the second portion.
Line:
html:<TR><TD>PICK_1</TD><TD>36.0000</TD><TD>1000000</TD><TD>26965</TD><TD>100000000</TD><TD>97074000</TD><TD>2926000</TD><TD>2.926%</TD><TD>97.074%</TD></TR>
I want to have the following results after grepping this line.
PICK_1 97.074%
Currently just grepping first portion via following command.
grep -Po "<TR><TD>[A-Z0-9_]+" test.txt
Appreciate any help on how I can go about doing this. Thanks.
Use awk with a custom field separator:
awk -F'[<>TDR/]+' '{ print $2, $(NF-1) }' file
This splits the line on things that look like one or more opening or closing <TD> or <TR> tags, and prints the second and second-last field.
Warning: this will break on almost every input except the one that you've shown, since awk, grep and friends are designed for processing text, not HTML.
If you always have the same number of fields delimited by "TD" tags, you can try with this (dirty) awk:
awk -F'[<TD>|</TD>]' '{print $8 " " $80}'
Or this combination of column and awk:
column -t -s "</TD>" | awk -F' ' '{print $3 " " $11}'
Or with sed instead of column:
sed -e 's/<TD>/ /g' | awk -F' ' '{print $3 " " $11}'
try provide each patter after "-e" option
grep -e PICK_1 -e "<TR><TD>[A-Z0-9_]+" test.txt
awk -F'[<>]' '{print $5,$(NF-4)}' file
PICK_1 97.074%

AWK alias not printing

The below awk command (copied and pasted from stackoverflow) works fine from the command line but doesnt print anything when aliased
awk '/WORD/ {print $3}' log.log | awk 'BEGIN{c=0} length($0){a[c]=$0;c++}END{p5=(c/100*5); p5=p5%1?int(p5)+1:p5; print a[c-p5-1]}'
alias getperc="awk '/WORD/ {print \$3}' log.log | awk 'BEGIN{c=0} length(\$0){a[c]=$0;c++}END{p5=(c/100*5); p5=p5%1?int(p5)+1:p5; print a[c-p5-1]}'"
I am fairly new to using bash. What am I missing here?
Don't use aliases. They require an additional layer of quoting, which is troublesome (as here), and they prevent you from being able to usefully parameterize or add conditional logic to your code.
A simple transliteration to a function is:
getperc() { awk '/WORD/ {print $3}' log.log | awk 'BEGIN{c=0} length($0){a[c]=$0;c++}END{p5=(c/100*5); p5=p5%1?int(p5)+1:p5; print a[c-p5-1]}'; }
A slightly more capable one, which will still use log.log by default, but which will also let you provide an alternate input file name (as in getperc alternate.log) or pipe to your function (as in cat alternate.log | getperc):
getperc() {
[[ -t 0 || $1 ]] || set -- - # use "-" (stdin) as input file if not a TTY
# ...this will let you pipe to your function.
awk '/WORD/ {print $3}' "${1:-log.log}" | awk 'BEGIN{c=0} length($0){a[c]=$0;c++}END{p5=(c/100*5); p5=p5%1?int(p5)+1:p5; print a[c-p5-1]}'
}
I think there is confusion by bash regarding $3 and $0 it thinks they are argument of the alias. you can verify this by
try this in bash
alias ech="echo {print \$3}"
it will print just
{print }
but now try
alias ech="echo {print \$\3}"
it will print what you expected
{print $3}
Let me know if this solves your problem

How do I print the result of a command with 'echo'?

How do print my full name with the following?
awk -F: '($1==U){print $5}' U=$LOGNAME /etc/passwd
Per example, but with the echo command with some words on sides:
For example,
Hello Diogo Saraiva, happy to see you again
Where Diogo Saraiva is my full name which I have in Ubuntu records.
I tried some things, but I have not accomplished that script...
Another thing: Why, when I issue awk -F: '($1==U){print $5}' U=$LOGNAME /etc/passwd, is Diogo Saraiva,,, shown instead of Diogo Saraiva?
This happens too with:
grep $USER /etc/passwd | awk 'BEGIN { FS=":" } { print $5 }'
I need for my script to declare a variable, "like", with the command, and then echo that variable "like" various times along my script.
To output the string you want you can use this command.
awk -F: -v U="$LOGNAME" '$1==U{print "Hello " $5 ", happy to see you again"}' /etc/passwd
If awk -F: -v U="$LOGNAME" '$1==U{print $5}' /etc/passwd is outputting Diogo Saraiva,,, then that is what is in your /etc/passwd file for that field.
To save the output from a command in a variable just use:
var=$(command)
And remember to quote the variable when you use it:
echo "Hello $var, happy to see you again"

Output result of cli command to a file using awk to get columns

I want to record the RSSI at a certain point with the distance that point is from a router. The distance will be user input and so will the output file name so the user will type something like:
sh rssi.sh output.csv 20
where output.csv is the csv I want to append the results to and 20 is the distance
at the moment rssi.sh looks like:
#!/bin/bash
RSSI_CSV=$1
DISTANCE=$2
RSSI=$(iwconfig wlan0 | awk -F'[ =]+' '/Signal level/ {print $7}\')
awk '{print $DISTANCE, $RSSI}' > $RSSI_CSV
This creates RSSI_CSV as per user input but doesn't print the required values in it and I'm not sure why.
I imagine it's
awk '{print $DISTANCE, $RSSI}' > $RSSI_CSV
that isn't working as echo RSSI or echo DISTANCE both output the values to the screen. I'm using awk as I want to have columns so i can output a csv file, perhaps though there is a better way?
There are a couple of issues with your awk need to pass the variables using the -v option and use the BEGIN block as no input is given. Also note that a single > will not append but overwrite the file. For appending you need >>:
awk -vD=$DISTANCE -vR=$RSSI 'BEGIN{print D,R}' >> $RSSI_CSV
Demo:
$ DISTANCE=20
$ RSSI=$(iwconfig wlan0 | awk -F'[ =]+' '/Signal level/ {print $7}')
$ awk -vD=$DISTANCE -vR=$RSSI 'BEGIN{print D,R}'
20 -47
Note: I believe you want comma separated values so:
$ awk -vD=$DISTANCE -vR=$RSSI 'BEGIN{print D","R}'
20,-47
However awk is overkill for printing variables just use good old echo:
$ echo "$DISTANCE,$RSSI"
20,-47
You don't need awk to print two shell variables.
printf "%s,%s\n" "$DISTANCE" "$RSSI" >> "$RSSI_CSV"

Resources