i am still writing a bash script and need your help !
I want to grep with two parameters, but it doesn't work.
This script stands in an until queue so it runs x times.
Please help me:
e=1
g=db_$((e++))
for call in $(cat /home/palyground/foo.xml |grep $HOME|grep db_$g| awk -F \" '{print $2}')
do
:
done
echo $call
My Problem is, that the $g is still standing by 1 and dont move to 2 3 eg.
I want to grep |grep db_1 in the first time in the second time |grep db_2 e.g.
Do you have any soulutions for this Problem ?
Try
g=$((++e))
for call in $(awk -F \" '$0~home && $0~db {print $2}' home="$HOME" db="db_$g" /home/palyground/foo.xml)
By changing to ++e it will starts with 1 instead of 0
So i get the right code now..
First time thank you very much Jotne and chepner !
The right code:
f=1
q=/home/playground/foo.xml
g=db_$((f++))
HOME_GREP=${DB_HOME}/${g}
var1=$(cat $q | grep ${HOME_GREP} )
var2=$(echo $var1| awk -F \" '{print $2}' )
echo $var2
Related
Struggling with this...
for i in `cat services.txt`
do
if ! grep -q $i; then
echo " $i Is NOT Running"
else
echo " Checking $i on `hostname`..."
ps aux | grep -i $i | awk '{print $1, $11}'| cut -d' ' -f1-2| sort
echo -e " "
sleep 4
fi
done
The block just hangs - Ive not been able to capture the success/failure of grep
If a string in services.txt is NOT found ... the script hangs... Id like for grep to skip it if not found
services.txt contain just single words
thanks!
The reason your script hangs is beacuse the command grep -q $i is waiting for an input. You can try running that command separately in a shell and verify that it prompts for an input.
Changing your command to ps aux | grep -i $i in the if statement should fix your issue.
NOTE: ps aux | grep -i $i lists grep also as one of the process. Make sure you exclude that process by piping it to another grep ps aux | grep -i $i | grep -v 'grep'
here is the working code
checkservices() {
cat >$HOME/services.txt <<EOF
ganglia
hbase
hdfs
hive
hue
livy
mapred
test-missing-service
mysql
oozie
presto
spark
yarn
zeppelin
EOF
for i in `cat $HOME/services.txt`
do
if `ps -ef | grep ^$i | grep -v grep >/dev/null`
then
i=$(echo "$i" | awk '{print toupper($0)}')
echo "$i -- is running on `hostname`"
echo ""
sleep 2
else
i=$(echo "$i" | awk '{print tolower($0)}')
echo "$i -- IS NOT running on `hostname` error"
echo ""
fi
done
}
Can anyone explain why the following doesn't work please?
list
the letter is d
the number is 4
the number is 2
the letter is g
script.sh
#!/bin/bash
cat "$1" | grep letter | array=($(awk '{print $4}'))
for i in "${array[#]}"
do
:
echo $i
done
If I run this bash script.sh list I expect the array to print d and g, but it doesn't. I think its because of how I am trying to set the array.
I think its because of how I am trying to set the array.
Each command in a pipeline | is run in a subshell - as a separate process. The parent process does not "see" variable changes from a child process.
Just:
array=($(grep letter "$1" | awk '{print $4}'))
or
array=($(awk '/letter/{print $4}' "$1"))
Run variable assignment in the parent shell.
You should assign the complete row of piped commands to a variable.
array=($(cat "$1" | grep letter | awk '{print $4}'))
The cat and grep command can be combined with awk, but why do you want an array?
I think you want the process each element in one loop, so first remove the double quotes:
for i in ${array[#]}
do
:
echo $i
done
Next, try to do this without an array
while read -r i; do
:
echo $i
done < <(awk '/letter/ {print $4}' "$1")
in bash script, I define a array:
array=$(awk '{print $4}' /var/log/httpd/sample | uniq -c | cut -d[ -f1)
Now, I want to translate this content to code in bash script:
"if there is NOT any element in array, it means array=nothing, then echo "nothing in array".
help me to do that??? Thanks a lot
*besides, I want to delete access_log's content periodically every 5min (/var/log/httpd/access_log). Please tell me how to do that??*
Saying:
array=$(awk '{print $4}' /var/log/httpd/sample | uniq -c | cut -d[ -f1)
does not define an array. This simply puts the result of the command into the variable array.
If you wanted to define an array, you'd say:
array=( $(awk '{print $4}' /var/log/httpd/sample | uniq -c | cut -d[ -f1) )
You can get the count of the elements in the array by saying echo "${#foo[#]}".
For checking whether the array contains an element or not, you can say:
(( "${#array[#]}" )) || echo "Nothing in array"
I need to know how many processes are running for a specific task (e.g. number of Apache tomcats) and if it's 1, then print the PID. Otherwise print out a message.
I need this in a BASH script, now when I perform something like:
result=`ps aux | grep tomcat | awk '{print $2}' | wc -l`
The number of items is assigned to result. Hurrah! But I don't have the PID(s). However when I attempt to perform this as an intermediary step (without the wc), I encounter problems. So if I do this:
result=`ps aux | grep tomcat | awk '{print $2}'`
Any attempts I make to modify the variable result just don't seem to work. I've tried set and tr (replace blanks with line-breaks), but I just cannot get the right result. Ideally I'd like the variable result to be an array with the PIDs as individual elements. Then I can see size, elements, easily.
Can anyone suggest what I am doing wrong?
Thanks,
Phil
Update:
I ended up using the following syntax:
pids=(`ps aux | grep "${searchStr}"| grep -v grep | awk '{print $2}'`)
number=${#pids[#]}
The key was putting the brackets around the back-ticked commands. Now the variable pids is an array and can be asked for length and elements.
Thanks to both choroba and Dimitre for their suggestions and help.
pids=($(
ps -eo pid,command |
sed -n '/[t]omcat/{s/^ *\([0-9]\+\).*/\1/;p}'
))
number=${#pids[#]}
pids=( ... ) creates an array.
$( ... ) returns its output as a string (similar to backquote).
Then, sed is called on the list of all the processes: for lines containing tomacat (the [t] prevents the sed itself from being included), only the pid is preserved and printed.
You may need to adjust the pgrep command (you may need or may not need the -f option).
_pids=(
$( pgrep -f tomcat )
)
(( ${#_pids[#]} == 1 )) &&
echo ${_pids[0]} ||
echo message
If you want to print the number of pids (with a message):
_pids=(
$( pgrep -f tomcat )
)
(( ${#_pids[#]} == 1 )) &&
echo ${_pids[0]} ||
echo "${#_pids[#]} running"
It should be noted that the pgrep utility and the syntax used are not standard.
First, I am not experienced in scripting, so be gentle with me
Anyway, I tried making a script for finding files by mime-type ( audio, video, text...etc), and here's the poor result I came up with.
#!/bin/bash
FINDPATH="$1"
FILETYPE="$2"
locate $FINDPATH* | while read FILEPROCESS
do
if file -bi "$FILEPROCESS" | grep -q "$FILETYPE"
then
echo $FILEPROCESS
fi
done
It works, but as you could guess, the performance is not so good.
So, can you guys help me make it better ? and also, I don't want to rely on files extensions.
Update:
Here's what I am using now
#!/bin/bash
FINDPATH="$1"
find "$FINDPATH" -type f | file -i -F "::" -f - | awk -v FILETYPE="$2" -F"::" '$2 ~ FILETYPE { print $1 }'
Forking (exec) is expensive. This runs the file command only once, so it is fast:
find . -print | file -if - | grep "what you want" | awk -F: '{print $1}'
or
locate what.want | file -if -
check man file
-i #print mime types
-f - #read filenames from the stdin
#!/bin/bash
find $1 | file -if- | grep $2 | awk -F: '{print $1}'
#!/usr/bin/env bash
mimetypes=$(sed -E 's/\/.*//g; /^$/d; /^#/d' /etc/mime.types | uniq)
display_help(){
echo "Usage: ${0##*/} [mimetype]"
echo "Available mimetypes:"
echo "$mimetypes"
exit 2
}
[[ $# -lt 1 ]] && display_help
ext=$(sed -E "/^${1}/!d; s/^[^ \t]+[ \t]*//g; /^$/d; s/ /\n/g" /etc/mime.types | sed -Ez 's/\n$//; s/\n/\\|/g; s/(.*)/\.*\\.\\(\1\\)\n/')
find "$PWD" -type f -regex "$ext"