0

I'm a beginner to bash scripting and been writing a script to check different log files and I'm bit stuck here.

clientlist=/path/to/logfile/which/consists/of/client/names 
#i will grep only the client name from the file which has multiple log lines 
clients=$(grep --color -i 'list of client assets:' $clientlist | cut -d":" -f1 )
echo "Clients : $clients"
#For example "Clients: Apple
#                      Samsung
#                      Nokia"
#number of clients may vary from time to time
assets=("$clients".log)
echo assets: "$assets"

The code above greps the client name from the log file and i'm trying to use the grepped client name (each) to construct a logfile with each client name.

The number of clients is indefinite and may vary from time to time.

The code I have returns the client name as a whole

assets: Apple
        Samsung
        Nokia.log

and I'm bit unsure of how to cut the string and pass it on one by one to return the assets which has .log for each client name. How can i do this ?

Apple.log
Samsung.log
Nokia.log

2 Answers 2

1

(Apologies if I have misunderstood the task)

Using awk

if your input file (I'll call it clients.txt) is:

Clients: Apple
         Samsung
         Nokia

The following awk step:

awk '{print $NF".log"}' clients.txt

outputs:

Apple.log
Samsung.log
Nokia.log

(You can pipe straight into awk and omit the file name if the pipe stream is as the file contents in the above example).

It is highly likely that a simple awk procedure can perform the entire task beginning with the 'clientlist' you process with grep (awk has all the functionality of grep built-in) but I'd need to know the structure of the origial file to extract the client names.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent! This actually worked for me. I had to omit the file name and pipe straight into awk and it worked. Thankyou so much.
1

One awk idea:

assets=( $(awk -F: '/list of client assets:/ {print $2".log"}' "${clientlist}") )

# or

mapfile -t assets < <(awk -F: '/list of client assets:/ {print $2".log"}' "${clientlist}")

Where:

  • -F: - define input field delimiter as :
  • /list of client assets:/ - for lines that contain the string list of clients assets: print the 2nd :-delimited field and append the string .log on the end

One sed idea:

assets=( $(sed 's/.*://; s/$/.log/' "${clientlist}") )

# or

mapfile -t assets < <(sed 's/.*://; s/$/.log/' "${clientlist}")

Where:

  • s/.*:// - strip off everything up to the :
  • s/$/.log/ - replace end of line with .log

Both generate:

$ typeset -p assets
declare -a assets=([0]="Apple.log" [1]="Samsung.log" [2]="Nokia.log")

$ echo "${assets[@]}"
Apple.log Samsung.log Nokia.log

$ printf "%s\n" "${assets[@]}"
Apple.log
Samsung.log
Nokia.log

$ for i in "${!assets[@]}"; do echo "assets[$i] = ${assets[$indx]}"; done
assets[0] = Apple.log
assets[1] = Samsung.log
assets[2] = Nokia.log

NOTE: the alternative answers using mapfile address the issue referenced in Charles Duffy comment (see bash pitfall #50); readarray is a synonym for mapfile

1 Comment

BashPitfalls #50 applies. Better to suggest readarray -t assets < <(...) than assets=( $(...) ) for populating an array from line-oriented input.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.