PROJECT_KEY=$(grep sonar.projectKey /home/karthik/sonar-project.properties | awk -F '=' '{print $$2}');
The output of the grep is not getting stored in the variable PROJECT_KEY
You need the shell function to call grep:
PROJECT_KEY=$(shell grep sonar.projectKey /home/karthik/sonar-project.properties | awk -F '=' '{print $$2}');
--------------^
GNU Make manual page: https://www.gnu.org/software/make/manual/make.html#The-shell-Function
Related
How to feed xargs to a piped grep for a piped cat command.
Command 1:
(Generates a grep pattern with unique PIDs for a particular date time, read from runtime.log)
cat runtime.log | grep -e '2018/09/13 14:50' | awk -F'[ ]' '{print $4}' | awk -F'PID=' '{print $2}' | sort -u | xargs -I % echo '2018/09/13 14:50.*PID='%
The output of above command is (It's custom grep pattern):
2018/09/13 14:50.*PID=13109
2018/09/13 14:50.*PID=14575
2018/09/13 14:50.*PID=15741
Command 2:
(Reads runtime.log and fetch the appropriate lines based on the grep pattern (Ideally the grep pattern should comes from command 1))
cat runtime.log | grep '2018/09/13 14:50.*PID=13109'
The question is How to combine both Command 1 & Command 2
Below combined version of command doesn't gives the expected output (The produced output had lines having the date other than '2018/09/13 14:50')
cat runtime.log | grep -e '2018/09/13 14:50' | awk -F'[ ]' '{print $4}' | awk -F'PID=' '{print $2}' | sort -u | xargs -I % echo '2018/09/13 14:50.*PID='% | cat runtime.log xargs grep
grep has an option -f. From man grep:
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore matches nothing. (-f is specified by POSIX .)
So you could use
cat runtime.log | grep -e '2018/09/13 14:50' | awk -F'[ ]' '{print $4}' | awk -F'PID=' '{print $2}' | sort -u | xargs -I % echo '2018/09/13 14:50.*PID='% > a_temp_file
cat runtime.log | grep -f a_temp_file
The shell has a syntax that avoids having to create the temporary file. <(). From man bash:
Process Substitution
Process substitution is supported on systems that support named pipes
(FIFOs) or the /dev/fd method of naming open files. It takes the form
of <(list) or >(list). The process list is run with its input or
output connected to a FIFO or some file in /dev/fd. The name of this
file is passed as an argument to the current command as the result of
the expansion. If the >(list) form is used, writing to the file will
provide input for list. If the <(list) form is used, the file passed
as an argument should be read to obtain the output of list.
So you can combine it to:
cat runtime.log | grep -f <(cat runtime.log | grep -e '2018/09/13 14:50' | awk -F'[ ]' '{print $4}' | awk -F'PID=' '{print $2}' | sort -u | xargs -I % echo '2018/09/13 14:50.*PID='%)
Output of awk '{print $4}' is
b05808aa-c6ad-4d30-a334-198ff5726f7c
59996d37-9008-4b3b-ab22-340955cb6019
2b41f358-ff6d-418c-a0d3-ac7151c03b78
7ac4995c-ff2c-4717-a2ac-e6870a5670f0
I need to grep file st.log by these records. Something like awk '{print $4}' |xargs -i grep -w "pattern from awk" st.log I dont know how to pass pattern correctly?
What about
awk '{print $4}' | grep -F -f - st.log
Credits to Eric Renouf, who noticed that -f - can be used for standard input instead -f <(cat), Note: -f /dev/stdin also works and avoids launching a new process.
or closer to the question to have the output ordered
awk '{print $4}' | xargs -i grep -F {} st.log
maybe -w was not the option OP needed but -F
grep --help
-F, --fixed-strings PATTERN is a set of newline-separated strings
-w, --word-regexp force PATTERN to match only whole words
-w will match only line that contain exactly pattern
examples
grep -w . <<<a # matches
grep -w . <<<ab # doesn't match
grep -F . <<<a # doesn't match
grep -F . <<<a.b # matches
May be something along these lines be helpful
How to process each line received as a result of grep command
awk '{print $4} | while read -r line; do
grep $line st.log
done
I have a problem with bash. I have big log file and I must check only a part of all log. In this purpose I use those expressions:
cat 29.log | grep -A 999 "15/02/06-22:30"
or
awk '$1>="15/02/06-22:30" {print$0}' 29.log
I want to change "15/02/06-22:30" at "date +%y/%m/d-%H:M" but when I use command
awk '$1>="date +%y/%m/d-%H:M" {print$0}' 29.log
or
awk '$1>='date +%y/%m/d-%H:M' {print$0}' 29.log
nothing happens.
Any ideas?
I need this in one command, not a script
You can pass shell variables to AWK using the -v flag:
awk -v d="$(date '+%y/%m/%d-%H:%M')" '$1>=d' 29.log
grep -A 999 `date '+%y/%m/d-%H:M'` 29.log
i want to svn blame lines of code which include "todo | fixme"
i have the general flow of the script but struggle to combine it into one
finding the lines with "todo"
grep --color -Ern --include=*.{php,html,phtml} --exclude-dir=vendor "todo|TODO|FIXME" .
blame the line of code
svn blame ${file} | cat -n |grep ${linenumber}
i could get $file and $linenumber from the first command with awk, but i dont know how to pipe the values i extract with awk into the second command.
i am missing the glue to combine these commands into one "script" (- :
You can build the command with awk and then pipe it to bash:
grep --color -Ern --include=*.{php,html,phtml} --exclude-dir=vendor "todo|TODO|FIXME" . |\
awk -F: '{printf "svn blame \"%s\" | cat -n | grep \"%s\"\n", $1, $2}'
That prints one command per input line with the following format:
svn blame "${file}" | cat -n | grep "${linenumber}"
The varibales are replaces. When you execute the command as above they are only printed to the shell, that you can comfirm if everything is right. If yes add a last pipe to the in of the command that the ouput is redirected to bash. The complete command would look like this:
grep --color -Ern --include=*.{php,html,phtml} --exclude-dir=vendor "todo|TODO|FIXME" . |\
awk -F: '{printf "svn blame \"%s\" | cat -n | grep \"%s\"\n", $1, $2}' | bash
A small notice: I think you want to print the line number extracterd in the first command, aren't you? But grep ${linenumber} just gives the line containing the string ${linenumber}. To print only the linenumber use that command: sed -n "2p" to print line number 2 for example. The complete command would then look like this:
grep --color -Ern --include=*.{php,html,phtml} --exclude-dir=vendor "todo|TODO|FIXME" . |\
awk -F: '{printf "svn blame \"%s\" | cat -n | sed -n \"%sp\"\n", $1, $2}' | bash
Why do these do different things?
ENTRY="banana#Apple"
HOST_ID=$ENTRY | awk -F '#' '{print $2}'
echo $HOST_ID
echo $ENTRY | awk -F '#' '{print $2}'
In the echo command, the data is displayed as expected. In the save to variable command, the data is not, and the variable is left empty.
This:
HOST_ID=$ENTRY | awk -F '#' '{print $2}'
means this:
HOST_ID='banana#Apple' | awk -F '#' '{print $2}'
In other words, you're running two commands in separate subshells — HOST_ID='banana#Apple', and awk -F '#' '{print $2}' — and piping the output of one to the other. This doesn't accomplish anything: HOST_ID='banana#Apple' produces no output, so the awk command gets no input, so it doesn't print anything. (And because of the subshells, even the HOST_ID='banana#Apple' part has no effect: it's setting that variable in a subshell, rather than in the parent shell that's running the overall command. So the value disappears almost immediately)
Instead, you want to write:
HOST_ID="$(echo "$ENTRY" | awk -F '#' '{print $2}')
or:
HOST_ID="$(awk -F '#' '{print $2}' <<< "$ENTRY")
or perhaps (if you're only ever expecting $ENTRY to have two fields):
HOST_ID="${ENTRY#*#}"