TMPFILE=/tmp/jboss_ps.$$
${PS} ${PS_OPTS} | \
grep ${JBOSS_HOME}/java | \
egrep -v " grep | \
tee | $0 " | ${AWK} '{print $NF " "}' | \
sort -u > ${TMPFILE} 2>/dev/null
I want to know what this precise line is doing from the code above
egrep -v " grep | \
tee | $0 "
At first i thought that that line is searching for everything that does not contain this exact string "grep | \ tee | $0" but it appears that egrep is processing the pipes, so what's the significance of the pipes here, does it mean OR ? From my test it appears that it's not, but if it means output redirection then what's the inner grep getting ? And why is tee alone too ?
AFAIK
egrep -v " grep | \
tee | $0 "
is nothing but
egrep -v " grep | tee | $0 "
where \ is the continuation character in bash.
egrep is same as grep -E
-v for inverted selection
tee just another string
so egrep -v " grep | tee | $0 " does find lines that have the string {java path} and within this results, all the lines that doesn't match the condition {either of grep OR tee OR $0 } where
$0 is the filename not a '$0' because it uses DOUBLE QUOTES and not single quotes :)
" commands | $variables " has the tendency to expand the variables and use the utility.
The commands in the pipeline before the egrep command is probably something like
ps -ef|grep .... The egrep -v (Option)line you asked about is simply omitting lines you
don't want in the results, in this case the initial grep command issued by the
script, any tee commands and lastly $0 which is the name of the this script
being executed. egrep allows to enter multiple patterns enclosed in double quotes and
separated by pipe symbol. Syntax egrep -[option or not] "patern1|patern2|patern..."
Related
Given a string with multiple words like below, all in one line:
first-second-third-201805241346 first-second-third-201805241348 first-second-third-201805241548 first-second-third-201705241540
I am trying to the maximum number from the string, in this case the answer should be 201805241548
I have tried using awk and grep, but I am only getting the answer as last word in the string.
I am interested in how to get this accomplished.
echo 'first-second-third-201805241346 first-second-third-201805241348 first-second-third-201805241548 first-second-third-201705241540' |\
grep -o '[0-9]\+' | sort -n | tail -1
The relevant part is grep -o '[0-9]\+' | sort -n | tail -n 1.
Using single gnu awk command:
s='first-second-third-201805241346 first-second-third-201805241348 first-second-third-201805241548 first-second-third-201705241540'
awk -F- -v RS='[[:blank:]]+' '$NF>max{max=$NF} END{print max}' <<< "$s"
201805241548
Or using grep + awk (if gnu awk is not available):
grep -Eo '[0-9]+' <<< "$s" | awk '$1>max{max=$1} END{print max}'
Another awk
echo 'first-...-201705241540' | awk -v RS='[^0-9]+' '$0>max{max=$0} END{print max}'
Gnarly pure bash:
n='first-second-third-201805241346 \
first-second-third-201805241348 \
first-second-third-201805241548 \
first-second-third-201705241540'
z="${n//+([a-z-])/;p=}"
p=0 m=0 eval echo -n "${z//\;/\;m=\$((m>p?m:p))\;};m=\$((m>p?m:p))"
echo $m
Output:
201805241548
How it works: This code constructs code, then runs it.
z="${n//+([a-z-])/;p=}" substitutes non-numbers with some pre-code
-- setting $p to the value of each number, (useless on its own). At this point echo $z would output:
;p=201805241346 \ ;p=201805241348 \ ;p=201805241548 \ ;p=201705241540
Substitute the added ;s for more code that sets $m to the
greatest value of $p, which needs eval to run it -- the actual
code the whole line with eval runs looks like this:
p=0 m=0
m=$((m>p?m:p));p=201805241346
m=$((m>p?m:p));p=201805241348
m=$((m>p?m:p));p=201805241548
m=$((m>p?m:p));p=201705241540
m=$((m>p?m:p))
Print $m.
I get the following error:
> echo "${$(qstat -a | grep kig):0:7}"
-bash: ${$(qstat -a | grep kig):0:7}: bad substitution
I'm trying to take the number before. of
> qstat -a | grep kig
1192530.perceus- kigumen lr_regul pbs.sh 27198 2 16 -- 24:00:00 R 00:32:23
and use it as an argument to qdel in openPBS so that I can delete all process that I started with my login kigumen
so ideally, this should work:
qdel ${$(qstat -a | grep kig):0:7}
so far, only this works:
str=$(qstat -a | grep kig); qdel "${str:0:7}"
but I want a clean one-liner without a temporary variable.
The shell substring construct you're using (:0:7) only works on variables, not command substitution. If you want to do this in a single operation, you'll need to trim the string as part of the pipeline, something like one of these:
echo "$(qstat -a | grep kig | sed 's/[.].*//')"
echo "$(qstat -a | awk -F. '/kig/ {print $1}')"
echo "$(qstat -a | awk '/kig/ {print substr($0, 1, 7)}')"
(Note that the first two print everything before the first ".", while the last prints the first 7 characters.) I don't know that any of them are particularly cleaner, but they do it without a temp variable...
qstat -u palle | cut -f 1 -d "." | xargs qdel
Kills all my jobs... normally I grep out the jobname(s) before cut'ing...
So I use a small script "idlist":
qstat -u palle | grep -E "*.in" | grep -E "$1" | cut -f 1 -d "." | xargs
To see all my "map_..." jobs:
idlist "map_*"
For killing all my "map_...." jobs:
idlist "map_*" | xargs qdel
yet another ways :
foreach m1 in $(qstat -a );do
if [[ $m1 =~ kig ]];then
m2=${m1%.kig}
echo "kig found $m2 "
break
fi
done
For example, if I execute
ps aux | awk '{print $1}' | xargs -I {} echo {}
I want to let the shell sleep for 1 second between each echo.
How can I change my shell command?
You can use the following syntax:
ps aux | awk '{print $1}' | xargs -I % sh -c '{ echo %; sleep 1; }'
Be careful with spaces and semicolons though. After every command in between brackets, semicolon is required (even after the last one).
Replace echo by some shell script named sleepecho containing
#!/bin/sh
sleep 1
echo $*
If your awk supports it:
ps aux | awk '{ system("sleep 1"); print $1 }' | xargs -I {} echo {}q
or skip awk and xargs altogether
ps aux | while read -r user rest;
echo $user
sleep 1;
done
Can someone explain why this command doesn't print out a list of PID without the newline?
I want output like:
1234 5678 123 456
I tried all these, and none of them work
ps -eww --no-headers -o pid,args | grep 'usr' | awk '{ printf "%d ", $1 }'
ps -eww --no-headers -o pid,args | grep 'usr' | awk '{ printf "%s ", $1 }'
ps -eww --no-headers -o pid,args | grep 'usr' | awk '{ print $1 }' | tr '\n' ''
ps -eww --no-headers -o pid,args | grep 'usr' | awk '{ print $1 }' | tr -d '\n'
I just found out bash works fine, but not zsh in my case
zsh has a feature of letting the user know that the last output line was partial (i.e. there were no final newline). For more details on this you can look up PROMPT_CR, PROMPT_SP and PROMPT_EOL_MARK in man zshoptions.
You can add PROMPT_EOL_MARK='' to your ~/.zshrc to make the partial line indicator empty, but I would advise against it: now we know that it's just a feature, and sometimes we can notice a problem with our data if we leave it enabled. On a reasonably powerful terminal, the percent sign (the default when PROMPT_EOL_MARK is unset) is output bold and inverted, so it can't be confused with a piece of actual output.
Your command's output is a list of pids exactly as you desired. Adding a final newline makes it also look right with zsh:
ps -eww --no-headers -o pid,args | awk '/usr/ { printf "%d ", $1 } END {print""}'
(using also another answer's idea of getting rid of grep using the power of awk).
It does for me like this:
ps -eww --no-headers -o pid,args | awk '/usr/{printf "%d ",$1}'
I.e. awk can search for strings matching regular expressions, so you don't really need grep when using awk.
I have a jar file, i need to execute the files in it in Linux.
So I need to get the result of the unzip -l command line by line.
I have managed to extract the files names with this command :
unzip -l package.jar | awk '{print $NF}' | grep com/tests/[A-Za-Z] | cut -d "/" -f3 ;
But i can't figure out how to obtain the file names one after another to execute them.
How can i do it please ?
Thanks a lot.
If all you need the first row in a column, add a pipe and get the first line using head -1
So your one liner will look like :
unzip -l package.jar | awk '{print $NF}' | grep com/tests/[A-Za-Z] | cut -d "/" -f3 |head -1;
That will give you first line
now, club head and tail to get second line.
unzip -l package.jar | awk '{print $NF}' | grep com/tests/[A-Za-Z] | cut -d "/" -f3 |head -2 | tail -1;
to get second line.
But from scripting piont of view this is not a good approach. What you need is a loop as below:
for class in `unzip -l el-api.jar | awk '{print $NF}' | grep javax/el/[A-Za-Z] | cut -d "/" -f3`; do echo $class; done;
you can replace echo $class with whatever command you wish - and use $class to get the current class name.
HTH
Here is my attempt, which also take into account Daddou's request to remove the .class extension:
unzip -l package.jar | \
awk -F'/' '/com\/tests\/[A-Za-z]/ {sub(/\.class/, "", $NF); print $NF}' | \
while read baseName
do
echo " $baseName"
done
Notes:
The awk command also handles the tasks of grep and cut
The awk command also handles the removal of the .class extension
The result of the awk command is piped into the while read... command
baseName represents the name of the class file, with the .class extension removed
Now, you can do something with that $baseName