Need help with looping through file contents

Hi,

I have a several files with ".out" extension in a folder and each file has the below like contents

....
appname: wonder1
.....
logname78.log
logname88.log
.....
CAP: 2
.....
appname: wonder54
......
logname28.log
logname58.log
logname54.log
.....
CAP: 3
.....
appname: wonder11
.....
logname92.log
.....
CAP: 1
.....

Where "...." can be bla bla bla any string.
Below is the desired output

wonder1


wonder54



wonder11


logname78.log
logname88.log

logname28.log
logname58.log
logname54.log

logname92.log

I run a for loop to traverse through the folder picking one file at a time.

for file in *.out
do
        for csfile in $(grep -F 'appname' $file | awk '{print $2}')
        do
                echo $csfile
                for counter in $(grep -F 'CAP:' $file | awk '{print $2}')
                do
                        let start=1
                        for i in {$start..$counter}
                        do
                                echo " "
                        done
                done
        done
        for logg in $(grep -F '.log' $file)
        do
             echo $logg
        done
     
echo " "
done

The above effort does not yield what i desire ...

Problem 1: The value of CAP remains always the same i.e the first vaue in the file.

Problem 2: The .log files are not seperated by blank lines as seen in the desired output.

Current output looks something like this

wonder1


wonder54


wonder11


logname78.log
logname88.log
logname28.log
logname58.log
logname54.log
logname92.log

I know the basics of loops but can u help me structure my code get the correct output.

I don't think that your output sample fits what your code snippet will print.
You might want to look into this and check if you could adopt and adapt:

awk '
/CAP/           {L=L ORS
                 for (i=1; i<=$2; i++) print ""
                }
/appname/       {print $2}
/^log/          {L=L $0 ORS}
END             {print L}
' $file
wonder1


wonder54



wonder11

logname78.log
logname88.log

logname28.log
logname58.log
logname54.log

logname92.log

1 Like

I will test it tmr, however is that another way to get the desired output.

From bash you could do (Based on RudiC's awk script):

for file in *.out
do
   log=""
   while read line
   do
      case "$line" in
          appname:\ *) echo "${line#* }"  ;;
          logname*)    printf -v log "%s%s\n" "$log" "$line" ;;
          CAP:\ *)     printf -v log "%s\n" "$log"
                       eval printf '%.0s\\n' {1..${line#* }} ;;
      esac
   done < $file
   printf "%s" "$log"
done

Edit: And if you don't like using eval (which can be wise) replace the eval line with:

declare -a "vals=({1..${line#* }})"
printf "%.0s\n" ${vals[@]} ;;
1 Like

A variation from Chubler_XL's post

br() {
    for (( c=1; c<=${1}; c++ )); do
        echo 
    done
}

for file in *.out; do
   log=""
   while read field1 field2; do
       case "$field1" in
           appname:)   echo "${field2}"  ;;
           logname*)   printf -v log "%s%s\n" "$log" "$field1" ;;
               CAP:)   printf -v log "%s\n" "$log"
                       br "${field2}" ;;
      esac
   done < "$file"
   printf "%s" "$log"
done