VMStat ran everyday at midnight with the time before each entry - linux

Trying to run a VMSTAT every 10 minutes (every 600 seconds 144 times a day) but would like to append the time at the beggining of each line.
0 00 * * * /usr/bin/vmstat 600 144|awk '{now=strftime("%T"); print now $0}' > /home/rory/rory_vmstat`date +\%d`
I keep getting a message in my mail saying:
/bin/sh: -c: line 0: unexpected EOF while looking for matching `''
/bin/sh: -c: line 1: syntax error: unexpected end of file
This works in the command line: /usr/bin/vmstat 600 144|awk '{now=strftime("%T"); print now $0}' so i'm not sure whats wrong.
I'm sure its nothing too complex, I tried switching the ' and " round but no luck. Any help will be greatly appreciated :)

You've escaped the last % character here date +\%d , you likely need to do the same with the first too:
strftime("\%T")
The issue being that cron converts % to a newline and sends the text after the % to stdin of the command, unless that % is escaped.

Related

Search for a String, and retrieve the line having it and all lines following it until another specific pattern

Using linux, I want to search a text file for the string Blah and then return the line full line that contained the string and all the lines following the pattern up until a line that contains the word Failed.
For example,
Test Case Name "Blah"
Error 1
Error 2
Error 3
Failed
Test Case Name "Foo"
Pass
Test Case Name "Red"
Pass
In the above, I want to search for "Blah", and then return:
Test Case Name "Blah"
Error 1
Error 2
Error 3
Up until the line Failed. There can be any number of "Error" lines between Blah and Failed.
Follow up to make it faster
Both sed and awk options worked.
sed '/Blah/!d;:a;n;/Failed/d;ba' file
and
awk '/Failed/{p=0}/Blah/{p=1}p;' file
However, I noticed that while returning the expected outcome is quite fast, it takes ages to exit. Maybe these commands are recurrently searching for Blah and given that it appears only once, they run until the end-of-file.
This would not be much of a problem but I'm working with a file that contains 10 million lines and for now it is painfully slowly.
Any suggestions on how to exit after finding both lines containing Blah and Failed would be much appreciated.
Thanks!
With sed:
sed '/Blah/,/Failed/!d;//{1!d;}' file
/Blah/: match lines from Blahto Failed
!d: do not delete previous matching lines
//{1!d;}: from lines matching the addresses (that is Blahand Failed), do not delete the first one 1!d.
This might work for you (GNU sed):
sed -n '/Blah/,/Failed/{/Failed/!p}' file
Print the lines between and including Blah to Failed unless the line contains Failed.
sed ':a;/Blah/!d;:b;n;/Failed/ba;bb' file
If a line does not contain Blah delete it. Otherwise, print the current line and fetch the next (n). If this line contains Failed delete it and begin next iteration. Otherwise, repeat until successful or end-of-file.
The first solution prevents Blah and Failed being printed if they inhabit the same line. The second alternative, allows this.
would you like do with awk?
awk '/Failed/{p=0}/Blah/{p=1}p;' file will works for you.

bash: Execute a string as a command

See my previous question on assembling a specific string here.
I was given an answer to that question, but unfortunately the information didn't actually help me accomplish what I was trying to achieve.
Using the info from that post, I have been able to assemble the following set of strings: gnuplot -e "filename='output_N.csv'" 'plot.p' where N is replaced by the string representation of an integer.
The following loop will explain: (Actually, there is probably a better way of doing this loop, which you may want to point out - hopefully the following code won't upset too many people...)
1 #!/bin/bash
2 n=0
3 for f in output_*.csv
4 do
5 FILE="\"filename='output_"$n".csv'\""
6 SCRIPT="'plot.p'"
7 COMMAND="gnuplot -e $FILE $SCRIPT"
8 $COMMAND
9 n=$(($n+1))
10 done
Unfortunately this didn't work... gnuplot does run, but gives the following error message:
"filename='output_0.csv'"
^
line 0: invalid command
"filename='output_1.csv'"
^
line 0: invalid command
"filename='output_2.csv'"
^
line 0: invalid command
"filename='output_3.csv'"
^
line 0: invalid command
...
So, as I said before, I'm no expert in bash. My guess is that something isn't being interpreted correctly - either something is being interpreted as a string where it shouldn't or it is not being interpreted as a string where it should? (Just a guess?)
How can I fix this problem?
The first few (relevant) line of my gnuplot script are the following:
(Note the use of the variable filename which was entered as a command line argument. See this link.)
30 fit f(x) filename using 1:4:9 via b,c,e
31
32 plot filename every N_STEPS using 1:4:9 with yerrorbars title "RK45 Data", f(x) title "Landau Model"
Easy fix - I made a mistake with the quotation marks. ("")
Essentially, the only reason why the quotation marks " and " are required around the text filename='output_"$n".csv' is so that this string is interpreted correctly by bash, before executing the command! So indeed it is correct that the program runs when the command gnuplot -e "filename='output_0.csv'" 'plot.p' is entered into the terminal directly, but the quotation marks are NOT required when assembling the string beforehand. (This is a bit difficult to explain, but hopefully it is clear in your mind the difference between the 2.)
So the corrected version of the above code is:
1 #!/bin/bash
2 n=0
3 for f in output_*.csv
4 do
5 FILE="filename='output_"$n".csv'"
6 SCRIPT='plot.p'
7 COMMAND="gnuplot -e $FILE $SCRIPT"
8 $COMMAND
9 n=$(($n+1))
10 done
That is now corrected and working. Note the removal of the escaped double quotes.

Extracting file using bash script -- error occur

I have created a bash script which will extract a tar.gz file which is decompressed 5 times and remain the last tar.gz file decompressed. When I execute this acript I got this error line 26: 0++: syntax error: operand expected (error token is "+") . Please see below script.
i=0
for tarfile in *.tar.gz
do
$(($i++))
[ $i = 5 ] && break
tar -xf "$tarfile"
done
What is the error about and what is the correct way to solve my problem which is extracting the file five times and remain the last file decompressed. Thanks in advance for those who help.
you want to change $(($i++)) to ((i++)). see https://askubuntu.com/questions/385528/how-to-increment-a-variable-in-bash
Let's deconstruct $(($i++)). going outwards, $i expands to 0. so we have the expression $((0++)). 0 can't be incremented since it is a value, not a variable. so you get your error message line 26: 0++: syntax error: operand expected (error token is "+").
The reason to use ((i++)) without a $ at the front is that the $ at the front would actually evaluate i. You don't want i to be evaluated here, you just want i to be incremented. (h/t the other guy)

Shell Script Count String Occurrence

I am working on a project and need help figuring out how to do a task.
I am going to be given a log file, and I need to parse through and count the amount of times something occurs at a certain minute.
For example, if I have a txt file:
Line 3: 0606 221241 successfully copied to **
Line 5: 0606 221242 successfully copied to **
Line 7: 0606 221242 successfully copied to **
Line 9: 0606 221342 successfully copied to **
I want to know how many times something was successfully copied at 2212
So far, I have the following code seperating only lines that have been successful copied and getting the dates seperate...
grep "successfully copied to" Text.log >> Success.txt
awk '{print ($1, $2)}' Success.txt > datesAndTimes.txt
This gives me
0606 221241
0606 221242
0606 221242
0606 221243
For some reason, I am having trouble figuring out how to count the amount of times each specific time (ex. 0606 2212) occurs. occurs.
I only need the minutes, not the seconds (the last two digits of the second column)
Eventually I want a log/txt file that says:
0606 2212 3
0606 2213 1
and so on....
If any one has any ideas, I'm having a bit of a brain fart.
Thank you in advance!
You can get this in awk one liner:
awk '{mm=substr($4, 1, 4); cnt[$3 " " mm]++} END{for(a in cnt) print a " " cnt[a]}' Text.log
Live Demo: http://ideone.com/w2h64d

HIVE: How can I pass a hiveconf that contains a single quote?

I would like to pass a hive arg that contains a single quote in a string. This causes the EMR Job to fail with the following error:
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
Command exiting with ret '255'
Desired Variable:
-hiveconf "myvar=Today's a great day for a test!"
Any ideas? Thanks.
try:
SET myvar="Today's a great day for a test!";
then call it:
SELECT * FROM myTable WHERE test_today=${hiveconf:myvar}
That worked for me when I tried it, but when I try:
SET myvar=Today's a great day for a test! (withoutquotes)
I get an error. Hope this helps

Resources