export temp from Witty pi 2 to a logfile - awk

i have installed a witty pi 2 on my RPI3
But i want to export the temp from it to a spcific file
i can run a script called witty.sh and then i need to press 8 or Ctrl + C to quit
>>> Current temperature: 33.50°C / 92.3°F
>>> Your system time is: Sat 01 Jul 2017 20:29:46 CEST
>>> Your RTC time is: Sat 01 Jul 2017 20:29:46 CEST
Now you can:
1. Write system time to RTC
2. Write RTC time to system
3. Synchronize time
4. Schedule next shutdown [25 15:04:00]
5. Schedule next startup [25 15:05:00]
6. Choose schedule script
7. Reset data...
8. Exit
What do you want to do? (1~8)
All i want is to export the first line.
I tried
sudo ./wittyPi.sh | grep Current | awk '{ print $4 }' > temp.log
but it´s ask me for a number and then give the temp in temp.log
Is it possible to insert some extra code to generete Ctrl + C or sometinhg in the end ?

Just use a here string to provide the input:
$ cat tst.sh
echo "Type something:" >&2
read foo
echo "$foo"
$ ./tst.sh <<<stuff | sed 's/u/X/'
Type something:
stXff
and if your shell doesn't support here strings then use a here document instead:
$ ./tst.sh <<EOF | sed 's/u/X/'
> stuff
> EOF
Type something:
stXff
So you'd do (you never need grep when you're using awk):
sudo ./wittyPi.sh <<<8 | awk '/Current/{ print $4 }' > temp.log
or:
sudo ./wittyPi.sh <<<8 | awk 'NR==1{ print $4 }' > temp.log

Maybe a better way is to take a look at the get_temperature() function in the "utilities.sh" file, and see how it is implemented. It only involves some I2C communications.

Related

How does awkArray[NR]=$0 and awkArray[NR]=$1 print the last number

$ cat num.log
10
20
1
77
22
05
$ cat num.log | sort -n
1
05
10
20
22
77
How does awkArray[NR]=$0 and awkArray[NR]=$1 print the last number.
My understanding is all records in num.log is passed in sorted order to awkArray ,then don't understand $0 ,$1. Works here
$ cat num.log | sort -n | awk ' { awkArray[NR]=$0} END {print awkArray[NR] }'
77
and without sort, it doesnt print anything. Why?
$ cat num.log | awk ' { awkArray[NR]=$0 } END { print awkArray[NR]}'
My take on finding the maximum number in a file was written for a windows environment (running under cmd.exe). In this environment only double quotes can be used to "protect" an awk script and even then it kind of prevents you from using double quotes within your script. The following will work, even for cases when there are exclusively negative numbers in the input file. It will return an empty line if the input file is empty:
awk "NR==1{max=$0} $0>max {max=$0} END {print max}" num.log
Special thanks to Ed Morton for his constructive advice (see comments below). Please follow his recommendation of using single quotes when running the script in a shell environment.

Increment input Variable Number in shell Script

I have a lot script in which it is reading the input parameter. I need to increment all the input parameter by 1. So in case if it 1 it need to be 2 & 2 need to 3 etc. Is there any unix command which can replace this in one go for all scripts instead of going to each scripts and doing it manually. I am new to Unix not sure if there is any way to do it. Below is the example. Appreciate any help on this.
Before Changes
#!/bin/ksh
hv_bus_date="CAST('$1' AS DATE FORMAT 'YYYYMMDD')"
hv_octs_sys_wid=$2
hv_act_id=$3
After Changes
#!/bin/ksh
hv_bus_date="CAST('$2' AS DATE FORMAT 'YYYYMMDD')"
hv_octs_sys_wid=$3
hv_act_id=$4
EDIT: To save output into Input_file(s) itself without a GNU awk try following(but make sure you run my 1st solution to see if output is looking correct).
Let's say we have scripts whose values we need to change.
-rw-rw-r-- 1 ubuntu ubuntu 83 Dec 8 14:34 file2.ksh
-rw-rw-r-- 1 ubuntu ubuntu 83 Dec 8 14:34 file1.ksh
Our awk script's name is script.ksh to make sure this script is NOT coming under its own radar :)
cat script.ksh
awk '
FNR==1{
close(out)
out="out"++count
rename=(rename?rename ORS:"") "mv " out OFS FILENAME
}
match($0,/\$[0-9]+/){
before=substr($0,1,RSTART)
value=substr($0,RSTART+1,RLENGTH)
rest=substr($0,RSTART+RLENGTH)
if(value<9){
value++
}
print before value rest > (out)
}
END{
if(rename){
system(rename)
}
}
' file*sh
Now when we run the above script by doing ./script.ksh and we can one of the file named file1.ksh see its contents have been changed now as follows.
BEFORE:
cat file1.ksh
hv_bus_date="CAST('$1' AS DATE FORMAT 'YYYYMMDD')"
hv_octs_sys_wid=$2
hv_act_id=$3
AFTER:
cat file1.ksh
hv_bus_date="CAST('$2' AS DATE FORMAT 'YYYYMMDD')"
hv_octs_sys_wid=$3
hv_act_id=$4
1st solution: Could you please try following, considering that your script names are ending with .sh extensions and this will NOT save output into Input_file(s), it will print output on terminal only for you to check output if its coming fine.
awk '
match($0,/\$[0-9]+/){
before=substr($0,1,RSTART)
value=substr($0,RSTART+1,RLENGTH)
rest=substr($0,RSTART+RLENGTH)
if(value<9){
value++
}
print before value rest
}
' *sh
2nd solution(With only newer versions of GNU awk): Once you are happy with results of above command and if you have gawk command then try following, this should save output into Input_file(s) itself. IMHO this needs gawk 4.1.0 + version.
awk -i inplace -v INPLACE_SUFFIX=.bak '
match($0,/\$[0-9]+/){
before=substr($0,1,RSTART)
value=substr($0,RSTART+1,RLENGTH)
rest=substr($0,RSTART+RLENGTH)
if(value<9){
value++
}
print before value rest
}
' *sh

How to output just the user of a running process

When I do ps aux | grep mongod, I get
mongod 53830 0.1 0.3 247276 27168 ? Sl Apr04 128:21 /var/lib/mongodb-mms-automation/mongodb-mms-monitoring-agent-5.4.4.366-1.rhel7_x86_64/mongodb-mms-monitoring-agent
mongod 104378 0.6 0.8 469384 71920 ? Ssl Mar22 571:03 /opt/mongodb-mms-automation/bin/mongodb-mms-automation-agent -f /etc/mongodb-mms/automation-agent.config -pidfilepath /var/run/mongodb-mms-automation/mongodb-mms-automation-agent.pid >> /var/log/mongodb-mms-automation/automation-agent-fatal.log 2>&1
mongod 104471 0.6 5.4 1993296 433624 ? Sl Mar22 578:03 /var/lib/mongodb-mms-automation/mongodb-linux-x86_64-3.4.13/bin/mongod -f /data/mdiag/data/automation-mongod.conf
However, I'm only interested in outputting user of the third entry, which runs the actual mongod process. I'd like the output to be just
mongod
How would I tweak around ps, grep, and awk to do this?
Pipe it to awk and search:
ps aux | grep mongod | awk '/bin\/mongod /{print $8}'
With that you can probably drop the grep and just let awk do the searching:
ps aux | awk '/bin\/mongod /{print $8}'
This is searching for the string "bin/mongod " anywhere in the record and then returning whatever is in the 8th position for that record.
Trying to use shell commands to get that user is most likely going to break. Can you start mongod using the PID option?
/var/lib/mongodb-mms-automation/mongodb-linux-x86_64-3.4.13/bin/mongod -f /data/mdiag/data/automation-mongod.conf --pidfilepath /run/mongodb-pid.txt
Then you can simply run ps $(cat /run/mongodb-pid.txt) to get only the specific process you want.
It is probably best to specify the pattern to match the end of the first part of the COMMAND field we are interested in. Also, using bracket expressions in place of \/ makes at least my eyes happier when looking at patterns for matching file paths.
ps aux | awk -v command=11 -v user=1 '$command ~ /[/]bin[/]mongod$/ { print $user }'
perhaps filter out agents?
$ ps aux | awk '/mongod/ && !/agent/{print $1}'
Following awk may help here.
ps aux | awk '/mongod/ && /automation-mongod.conf/{print $8}'
OR
ps aux | awk '/mongod/ && /\/data\/mdiag\/data\/automation-mongod.conf/{print $8}'

copy to clipboard the last n commands in a terminal

I want to copy to clipboard something like this
$ command1
$ command2
If you run history you will get the commands in reverse order, so I want to just skip a number of lines from the tail and replace the entry line number with '$'. As you probably suspect this is a very useful shorthand when having to log your workflow or write documentation.
Example:
$ history
1340 pass
1341 pass insert m clouds/cloud9
1342 pass insert -m clouds/cloud9
1343 sudo service docker start
1344 history
So how do you turn that into:
$ sudo service docker start
$ pass insert -m clouds/cloud9
...etc
Assigning $1 works but it will leave a leading space
history | awk '{$1=""; print}'
If you want to copy this to the clipboard, you can use xclip
history | awk '{$1=""; print}' | xclip
Credit goes to https://stackoverflow.com/a/4198169/2032943
maybe you can use these;
history | tac | awk 'NR>1&&NR<=3 {$1="$";print $0}'
tac - concatenate and print files in reverse
NR<=3 : means that the last two commands before history.
NR>1 : to delete history command in history
$1="$" : to replace line numbers to $
test :
$ echo first
first
$ echo second
second
$ history | tac | awk 'NR>1&&NR<=3 {$1="$";print $0}'
$ echo second
$ echo first

Problem with awk and grep

I am using the following script to get the running process to print the id, command..
if [ "`uname`" = "SunOS" ]
then
awk_c="nawk"
ps_d="/usr/ucb/"
time_parameter=7
else
awk_c="awk"
ps_d=""
time_parameter=5
fi
main_class=RiskEngine
connection_string=db.regression
AWK_CMD='BEGIN{printf "%-15s %-6s %-8s %s\n","ID","PID","STIME","Cmd"} {printf "%-15s %-6s %-8s %s %s %s\n","MY_APP",$2,$time_parameter, main_class, connection_string, port}'
while getopts ":pnh" opt; do
case $opt in
p) AWK_CMD='{ print $2 }'
do_print_message=1;;
n) AWK_CMD='{printf "%-15s %-6s %-8s %s %s %s\n","MY_APP",$2,$time_parameter,main_class, connection_string, port}' ;;
h) print "usage : `basename ${0}` {-p} {-n} : Returns details of process running "
print " -p : Returns a list of PIDS"
print " -n : Returns process list without preceding header"
exit 1 ;
esac
done
ps auxwww | grep $main_class | grep 10348 | grep -v grep | ${awk_c} -v main_class=$merlin_main_class -v connection_string=$merlin_connection_
string -v port=10348 -v time_parameter=$time_parameter "$AWK_CMD"
# cat /etc/redhat-release
Red Hat Enterprise Linux AS release 4 (Nahant Update 6)
# uname -a
Linux deapp25v 2.6.9-67.0.4.EL #1 Fri Jan 18 04:49:54 EST 2008 x86_64 x86_64 x86_64 GNU/Linux
When I am executing the following from the script independently or inside script
# ps auxwww | grep $main_class | grep 10348 | grep -v grep | ${awk_c} -v main_class=$merlin_main_class -v connection_string=$merlin_connection_string -v port=10348 -v time_parameter=$time_parameter "$AWK_CMD"
I get two rows on Linux:
ID PID STIME Cmd
MY_APP 6217 2355352 RiskEngine 10348
MY_APP 21874 5316 RiskEngine 10348
I just have one jvm (Java command) running in the background but still I see 2 rows.
I know one of them (Duplicate with pid 21874) comes from awk command that I am executing. It includes again the main class and the port so two rows. Can you please help me to avoid the one that is duplicate row?
Can you please help me?
AWK can do all that grepping for you.
Here is a simple example of how an AWK command can be selective:
ps auxww | awk -v select="$mainclass" '$0 ~ select && /10348/ && ! (/grep/ || /awk/) && {print}'
ps can be made to selectively output fields which will help a little to reduce false positives. However pgrep may be more useful to you since all you're really using is the PID from the result.
pgrep -f "$mainclass.*10348"
I've reformatted the code as code, but you need to learn that the return key is your friend. The monstrously long pipelines should be split over multiple lines - I typically use one line per command in the pipeline. You can also write awk scripts on more than one line. This makes your code more readable.
Then you need to explain to us what you are up to.
However, it is likely that you are using 'awk' as a variant on grep and are finding that the value 10348 (possibly intended as a port number on some command line) is also in the output of ps as one of the arguments to awk (as is the 'main_class' value), so you get the extra information. You'll need to revise the awk script to eliminate (ignore) the line that contains 'awk'.
Note that you could still be bamboozled by a command running your main class on port 9999 (any value other than 10348) if it so happens that it is run by a process with PID or PPID equal to 10348. If you're going to do the job thoroughly, then the 'awk' script needs to analyze only the 'command plus options' part of the line.
You're already using the grep -v grep trick in your code, why not just update it to exclude the awk process as well with grep -v ${awk_c}?
In other words, the last line of your script would be (on one line and with the real command parameters to awk rather than blah blah blah).:
ps auxwww
| grep $main_class
| grep 10348
| grep -v grep
| grep -v ${awk_c}
| ${awk_c} -v blah blah blah
This will ensure the list of processes will not containg any with the word awk in it.
Keep in mind that it's not always a good idea to do it this way (false positives) but, since you're already taking the risk with processes containing grep, you may as well do so with those containing awk as well.
You can add this simple code in front of all your awk args:
'!/awk/ { .... original awk code .... }'
The '!/awk/' will have the effect of telling awk to ignore any line containing the string awk.
You could also remove your 'grep -v' if you extended my awk suggestion into something like:
'!/awk/ && !/grep/ { ... original awk code ... }'.