Skip to content
Advertisement

Read and run different command based on each line of file in Bash Linux?

I am completely new to bash scripting. I am trying to write a script in order to read line by line recent_log.txt which has the following content:

admin@bi01:/var/cache/logs$ head  recent_log.txt
./calisto/tomcat6-energy/calls.log.2016-03-05
./calisto/tomcat6-energy/calls_flush.log.2016-03-05.gz
./calisto/tomcat6-energy/catalina.2016-03-05.log.gz
./calisto/tomcat6-energy/energy-receive.log.2016-03-05.gz
./calisto/tomcat6-energy/energy.log.2016-01-01.gz
./calisto/tomcat6-energy/energy.log.2016-01-02.gz
./calisto/tomcat6-energy/energy.log.2016-01-03.gz
./calisto/tomcat6-energy/energy.log.2016-01-04.gz
./calisto/tomcat6-energy/energy.log.2016-01-05.gz
./calisto/tomcat6-energy/energy.log.2016-01-06.txt

and then run the command below for each line depend on the suffix. Output should be in another file. each output should have 2 lines space between them.

zcat users_energy.log.2016-03-20.gz | head -n5

This is my solution so far and I am not sure how should I complete it:

RAW_LOG_DIR=/var/cache/logs/recent_log.txt
OUTPUT_DIR=/var/cache/logs/output

for LOG in $RAW_LOG_DIR; do
   zcat -f ${RAW_LOG_DIR} | head -n5 > OUTPUT_DIR
done

Would you please to help me to how can I differentiate between cat or zcat ,.. and how to complete my code?

Advertisement

Answer

I think you’re looking for something like this:

raw_log_dir=/var/cache/logs/recent_log.txt
output_dir=/var/cache/logs/output
i=0

while read -r line; do
    (( i > 0 )) && printf 'nn'
    i=$(( i + 1 ))

    if [[ $line = *.gz ]]; then
        zcat "$line" | head -n5
    else
        head -n5 "$line"
    fi
done < "$raw_log_dir" > "$output_dir"

Read each line of the file in $raw_log_dir (always quote variables, read lines with while read, not for). If the line ends in .gz, then use zcat, else just use head directly. Redirect the output of the loop to the other file. Note my use of lowercase variable names, which is considered good practice, as uppercase ones may clash with those used by the shell.

The first two lines of the loop add two blank lines before the output for every line after the first. On some shells you can do this more succinctly by using (( i++ > 0 )) && printf 'nn' but ++ isn’t a standard feature so this way is more portable.

To check whether files exist before attempting to read them, you can add a line like this to the top of your loop:

[[ -f $line ]] || continue
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement