How to execute linux command from rakefile? - ruby

I have the following command:
ps -ef | awk '{if( $8~"java" || $8~"ruby" || $8~"god"){printf("Killing : %s \n",$2);{system("kill -9 "$2)};}};'
How do i excute this linux command from rakeFile.
I tried:
task :kill_process do
`ps -ef | awk '{if( $8~"java" || $8~"ruby" || $8~"god"){printf("Killing : %s \n",$2);{system("kill -9 "$2)};}};'`
end
But on executing it's giving error:
awk: cmd. line:1: {if( $8~"java" || $8~"glassfish" || $8~"ruby" || $8~"god" || $8~"couch"){printf("Killing : %s
awk: cmd. line:1: ^ unterminated string
awk: cmd. line:1: {if( $8~"java" || $8~"glassfish" || $8~"ruby" || $8~"god" || $8~"couch"){printf("Killing : %s
awk: cmd. line:1: ^ syntax error
I got the solution for my problem:
Thanks to #Yurii Verbytskyi
task :kill_process do
system %q(ps -ef | awk '{if( $8~"java" || $8~"ruby" || $8~"god"){printf("Killing : %s \n",$2);{system("kill -9 "$2)};}}')
end

Try this one.
task :kill_process do
system("ps -ef | awk '{if( $8~\"java\" || $8~\"ruby\" || $8~\"god\"){printf(\"Killing : %s \\n\",$2);{system(\"kill -9 \"$2)};}};'")
end
We need to escape special chars like \n

Related

Syntax Error in AWK, with no value come in print [duplicate]

This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
How do I use shell variables in an awk script?
(7 answers)
Closed 2 years ago.
My code is
ip=$(awk -F, "IGNORECASE = 1; $4 ~ /$line/ {print $4}" $today-combined.csv | wc -l)
html=$(awk -F, "IGNORECASE = 1; $5 ~ /$line/ {print $5}" $today-combined.csv | wc -l)
when i do sh -x test.sh , i got this
++ awk -F, 'IGNORECASE = 1; ~ /eg/ {print }' 2021-01-16-combined.csv
++ wc -l
awk: cmd. line:1: IGNORECASE = 1; ~ /eg/ {print }
awk: cmd. line:1: ^ syntax error
+ ip=0
++ awk -F, 'IGNORECASE = 1; ~ /eg/ {print }' 2021-01-16-combined.csv
++ wc -l
awk: cmd. line:1: IGNORECASE = 1; ~ /eg/ {print }
awk: cmd. line:1: ^ syntax error
+ html=0
I am not sure where I am getting a syntax error.
I try that also
ip=$(awk -F, 'IGNORECASE = 1; $4 ~ /$line/ {print $4}' $today-combined.csv | wc -l)
html=$(awk -F, 'IGNORECASE = 1; $5 ~ /$line/ {print $5}' $today-combined.csv | wc -l)
but it wont pick $line value.
I try / before ' but no result for that too.
Any help?

Assign and storing the varible of total number of lines of a file to use in the next command in shell & awk script

Please let me know the mistake in the following command
for i in file*; do printf "$i processing" && \
for j in {3..10}; do printf ">=$j\t" && k=$(< "$i" wc -l) ; \
awk 'BEGIN {FS="\t"} {if ($7 >= '$j') {print $0} }' $i| \
awk 'END{print (NR/"$k")*100}' ; done ; done
file1 processong
>=3 awk: cmd. line:1: (FILENAME=- FNR=126052) fatal: division by zero attempted
>=4 awk: cmd. line:1: (FILENAME=- FNR=118562) fatal: division by zero attempted
>=5 awk: cmd. line:1: (FILENAME=- FNR=113376) fatal: division by zero attempted
>=6 awk: cmd. line:1: (FILENAME=- FNR=109501) fatal: division by zero attempted
>=7 awk: cmd. line:1: (FILENAME=- FNR=106388) fatal: division by zero attempted
>=8 awk: cmd. line:1: (FILENAME=- FNR=103781) fatal: division by zero attempted
>=9 awk: cmd. line:1: (FILENAME=- FNR=101547) fatal: division by zero attempted
>=10 awk: cmd. line:1: (FILENAME=- FNR=99552) fatal: division by zero attempted
Thanks
The reason you obtain division by zero is due to the following line:
awk 'END{print (NR/"$k")*100}'
You attempt to use a shell variable $k which you assigned as k=$(< "$i" wc -l). However, you use it in a single quoted string, so bash does not perform the variable substitution as you imagine. It only does this in double-quoted strings. More details here: How do I use shell variables in an awk script?
So your mystery line should look like:
for i in file*; do
printf "$i processing" && \
for j in {3..10}; do
printf ">=$j\t" && k=$(< "$i" wc -l)
awk -v j="$j" 'BEGIN {FS="\t"} {if ($7 >= j) {print $0} }' $i \
| awk -v k="$k" 'END{print (NR/k)*100}'
done
done
However, this command can be cleaned up a lot:
no need for compound commands using &&. (printf will not fail)
Don't use printf "string", but rather printf -- "%s" "string"
when using awk, you are not in need of anything of the form like grep, wc, sed, ...
for i in file*; do
printf -- "%s" "$i processing"
for j in {3..10}; do
printf -- "%s" ">=$j\t"
awk -v j="$j" 'BEGIN {FS="\t"}($7>j) { print; c++ }END{print (c/NR)*100}' "$i"
done
done
Using GNU awk, you can even reduce this entire code-block into a single-awk, but this is beyond the scope of this question.

awk: cmd. line:1: { print \$9} : syntax error

I am trying to run the following command to get the "gis" & "cpu" usage from shell script. However when i try to run this command even manually, then i am getting the below error.
Any senior/expert please help on this.
$ top -b | head -n 8 | grep -w gis | awk '{ print \$9}'
awk: cmd. line:1: { print \$9}
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: { print \$9}
awk: cmd. line:1: ^ syntax error
$ top -b | head -n 8 | grep -w gis | awk '{ print \$10}'
# Same error i am getting for second command as well.
You don't need to escape the $. You are using single quotes, so the shell won't interpolate the $9. If you were using double quotes, you would need to escape it.
So, you have to...
top -b | head -n 8 | grep -w gis | awk '{ print $9}'
or
top -b | head -n 8 | grep -w gis | awk "{ print \$9}"

Invoking 'date' command inside awk string, with +%a formatting

Still newish to the site, but here goes...
Basically I'm storing events in multiple files, with each event being a line and each line containing dates ($1), start($2) and stop($3) times and several other pieces of data. I use two double underscores ("__") as Field Separators. I've been using a variety of shell scripts to manage the data, and I was using awk to calculate stats and I'm having trouble invoking the date function so I can get a total by day of the week. After much tinkering and scanning of discussion boards I got to this:
ls /home/specified/folder/MBRS.db/* |
xargs -n 1 -I % awk -F"__" '$6 == "CLOSED" && $1 >= "'$backDATE'" { print $0 }' % |
awk 'BEGIN{FS="__"}{specDATE=system("date --date="$1" +%a")} specDATE == "Tue" {print $2" "$3}'
or
ls /home/lingotech/Einstein/data/MBRS.db/* |
xargs -n 1 -I % awk -F"__" '$6 == "CLOSED" && $1 >= "'$backDATE'" { print $0 }' % |
awk 'BEGIN{FS="__"}system("date --date="$1" +%a") == "Mon" {print $2" "$3}'`
Instead of outputting the start and stop times, I'm getting a list of all the different days of the week for each entry.
I've tried more variations of the date usage than I care to admit, including:
for y in Sun Mon Tue Wed Thu Fri Sat; do
for directory in $( ls /home/specified/directory/MBRS.db/* | xargs -n 1 ); do
printf "."
[[ $( cat $directory | awk -F"__" '$6 == "CLOSED" && $1 >= "'$backDATE'" { print $1 }' | xargs -n 1 -I z date +%a -d z ) == "$y" ]] && echo BLAH
done
done
Some helpful explanation of what I'm screwing up would be much appreciated. Thanks in advance. Oh and I'm storing the date in YYMMDD format but that doesn't seem to be an issue for ubuntu server's version of 'date'.
I don't know about all the rest of it (too much text for my reading tastes!) but wrt the answer you posted, this part of it:
awk 'BEGIN{FS="__"} NF == 10 && $1 >= "'$backDATE'" && $4 == "'$x'" && $6 == "CLOSED" {while ( "date +%a -d "$1"" | getline newDAY){if (newDAY == "'$y'") print $2" "$3}}' /home/absolute/path/*
assuming it does what you want would be written as:
awk -v backDATE="$backDATE" -v x="$x" -v y="$y" '
BEGIN { FS="__" }
(NF == 10) && ($1 >= backDATE) && ($4 == x) && ($6 == "CLOSED") {
cmd = "date +%a -d \"" $1 "\""
while ( (cmd | getline newDAY) > 0 ) {
if (newDAY == y) {
print $2, $3
}
}
close(cmd)
}
' /home/absolute/path/*
wrt why use awk variables instead of letting shell variables expand to become part of the body of a shell script, the answer is robustness and simplicity.
This is letting a shell variable expand to become part of the body of an awk script:
$ x="hello world"
$ awk 'BEGIN{ print '$x' }'
awk: cmd. line:1: BEGIN{ print hello
awk: cmd. line:1: ^ unexpected newline or end of string
$ awk 'BEGIN{ print "'$x'" }'
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1: ^ unterminated string
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1: ^ syntax error
$ awk 'BEGIN{ print "'"$x"'" }'
hello world
$ x="hello
world"
$ awk 'BEGIN{ print "'"$x"'" }'
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1: ^ unterminated string
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1: ^ syntax error
and this is using an awk variable initialized with the value of a shell variable:
$ x="hello world"
$ awk -v x="$x" 'BEGIN{ print x }'
hello world
$ x="hello
world"
$ awk -v x="$x" 'BEGIN{ print x }'
hello
world
See the difference?
As for why store the command in a variable - because you have to close it after you use it and it must be spelled exactly the same way in the close command as it was when you opened the pipe. Compare:
cmd = "date +%a -d \"" $1 "\""
cmd | getline
close(cmd)
vs:
"date +%a -d \"" $1 "\"" | getline
close("date +%a -d \"" $l "\"")
and take an extremely close second look to spot the bug in the 2nd version.
Ok, so I ended up using this:
>backDATE=150000;
> for x in $listOFsites; do
> for y in Sun Mon Tue Wed Thu Fri Sat; do
> totalHOURS=$( awk 'BEGIN{FS="__"} NF == 10 && $1 >= "'$backDATE'" && $4 == "'$x'" && $6 == "CLOSED" {while ( ( "date +%a -d \""$1"\"" | getline newDAY) > 0 ){if (newDAY == "'$y'") print $2" "$3}}' /home/absolute/path/* | xargs -I % /home/custom/duration/calc % | paste -sd+ | bc ); printf ".";
> done
> done
I had to use date inside the single quotes (so that I could pass $1 to it) rather than outside (using -F"__" -v newDAY=...), but inside the single quotes getting the output of system() is problematic. After seeing:How can I pass variables from awk to a shell command? I finally saw the while (cmd | get line x) format which was the crux of my issue. Props to Ed Morton

Eval awk command with single quotes

I have a function "checkExist" that takes in a command and executes it based on whether or not the output file already exists. I pass a command like this, where file1 and file2 are just the names of output files that the commands create, so if they already exist it will ask if you want to overwrite, else it will skip:
checkExist file1 file2 command1 command2
In actual use like this:
checkExist 1.txt 2.txt "echo $1 | awk '$5 <= 10 {print $3, $4}'" "echo $2 | awk '$5 <= 10 {print $3, $4}'"
$1 and $2 above are inputs to the script "smartfilter.sh" containing the function checkExist within. So they are just file inputs.
Later in the checkExist function if the user types 'Y/y' to overwrite, or the files don't already exist then it will
eval $3 &
eval $4 &
wait
And I get an error like so:
awk: >= 10 {print , }
awk: ^ syntax error
awk: >= 10 {print , }
awk: ^ syntax error
awk: >= 10 {print , }
awk: ^ syntax error
awk: cmd. line:1: >= 10 {print , }
awk: cmd. line:1: ^ unexpected newline or end of string
I know it is to do with the single quotations ' around the awk and eval not parsing them correctly. I have tried \' but that doesn't work either. Is there a proper way to do this?
checkExist 1.txt 2.txt "echo $1 | awk '\$5 <= 10 {print \$3, \$4}'" "echo $2 | awk '\$5 <= 10 {print \$3, \$4}'"

Resources