0

I have below for loop in shell script

#!/bin/bash

#Get the year 
curr_year=$(date +"%Y")

FILE_NAME=/test/codebase/wt.properties

key=wt.cache.master.slaveHosts=

prop_value=""

getproperty(){

    prop_key=$1

    prop_value=`cat ${FILE_NAME} | grep ${prop_key} | cut -d'=' -f2`
}
#echo ${prop_value}

getproperty ${key}

#echo "Key = ${key}; Value="${prop_value}

arr=( $prop_value )

for i in "${arr[@]}"; do 

echo $i  | head -n1 | cut -d "." -f1

done

The output I am getting is as below.

test1
test2
test3

I want to process the test2 from above results to below script in place of 'ABCD'

grep test12345 /home/ptc/storage/**'ABCD'**/apache/$curr_year/logs/access.log* | grep GET > /tmp/test.access.txt

I tried all the options but could not able to succeed as I am new to shell scripting.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • you can change the fonction call to be a bit cleaner getproperty(){ return `cat ${FILE_NAME} | grep ${1} | cut -d'=' -f2` } prop_value=getproperty ${key} i am not sure to understand what you want to do, just add – Froggiz Sep 02 '15 at 12:33
  • echo $i | head -n1 | cut -d "." -f1 can be replaced by ${i%%.*} – Froggiz Sep 02 '15 at 12:43
  • @Froggiz Shell functions can't `return` strings. – Etan Reisner Sep 02 '15 at 13:00
  • Can you show us a sample input file? And you are trying to do what with the results of the first script? Run `N` commands of the second form with each output value in place of `ABCD`? – Etan Reisner Sep 02 '15 at 13:02
  • @Froggiz Unless you want to use [pass by reference](http://stackoverflow.com/a/14852461/2908724). – bishop Sep 02 '15 at 13:03
  • See http://stackoverflow.com/help/mcve -- surely you can use less code to demonstrate the limitation more clearly and succinctly (and in a self-contained way, to boot). – Charles Duffy Sep 02 '15 at 13:04
  • That said, there are a bunch of bugs here you might want to fix yourself first; run through http://shellcheck.net/ and address what it finds. – Charles Duffy Sep 02 '15 at 13:04
  • ...also, if this is a "how can I do X?" question, does X really have anything at all to do with the code you gave us, other than determining its input values? There are a bunch of bugs in what you're doing already -- `arr=( $prop_value )` is horrid practice; look at what happens when your value contains a `*`, for instance -- but those bugs are probably not actually that closely related to what you're actually asking for. – Charles Duffy Sep 02 '15 at 13:06
  • Also, are your `*`s in your sample code for emphasis, or are they literal, or are they some mix of the two? – Charles Duffy Sep 02 '15 at 13:07
  • getproperty(){ echo cat ${FILE_NAME} | grep ${1} | cut -d'=' -f2 } prop_value=$(getproperty ${key}) like that it can ! return can be use for if statement – Froggiz Sep 02 '15 at 13:08
  • That code's *wrong*. Again, run it through http://shellcheck.net/. – Charles Duffy Sep 02 '15 at 13:09
  • `getproperty() { cat "$FILE_NAME" | grep -F "$1" | cut -d= -f2; }; prop_value=$(getproperty "$key")` would be a little less wrong -- at least it doesn't have string-splitting and glob expansion where you don't want them. – Charles Duffy Sep 02 '15 at 13:10
  • BTW, the curly braces in `getproperty ${key}` do nothing at all to improve correctness -- it has the exact same bugs that `getproperty $key` has, which `getproperty "$key"` fixes. – Charles Duffy Sep 02 '15 at 13:15
  • As an aside, FILE_NAME should by convention have at least one lower-case character. See conventions for naming environment variables (and thus shell variables, with which they share a namespace) in the fourth paragraph of the relevant POSIX spec at http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html. – Charles Duffy Sep 02 '15 at 13:18
  • Also: `cat $filename | grep` is silly; much more efficient to run `grep <"$filename"`, giving `grep` a direct handle on the file rather than making it read from a pipeline from a separate process holding the handle. But, if you *must* make useless use of cat, at least make it `cat "$filename" | grep`, to avoid string-splitting and glob-expanding the filename. – Charles Duffy Sep 02 '15 at 13:19

1 Answers1

0

Ignoring the many bugs elsewhere and focusing on the one piece of code you say you want to change:

for i in "${arr[@]}"; do 
  val=$(echo "$i" | head -n1 | cut -d "." -f1)
  grep test12345 /dev/null "/home/ptc/storage/$val/apache/$curr_year/logs/access.log"* \
    | grep GET
done > /tmp/test.access.txt

Notes:

  • Always quote your expansions. "$i", "/path/with/$val/"*, etc. (The * should not be quoted on the assumption that you want it to be expanded).
  • for i in $prop_value would have the exact same (buggy) behavior; using arr buys you nothing. If you want using arr to increase correctness, populate it correctly: read -r -a arr <<<"$prop_value"
  • The redirection is moved outside the loop -- that way the second iteration through the loop doesn't overwrite the file written by the first one.
  • The extra /dev/null passed to grep ensures that its behavior is consistent regardless of the number of matches; otherwise, it would display filenames only if more than one matching log file existed, and not otherwise.
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441