Skip to content
Advertisement

Split file into multiple when special char met

I have a main file as following :

/* ------------- AAAAAAAA ------------- */
some
lines 
here
/* ------------- BBBBBBBB ------------- */
more
things
/* ------------- CCCCCCCC ------------- */
there
a 
few
more
lines

My final goal is to create a file that will containt only block that contains a specific string, for example if that string would be lines then I would have an output file like this :

/* ------------- AAAAAAAA ------------- */
some
lines 
here
/* ------------- CCCCCCCC ------------- */
there
a 
few
more 
lines

To reach my objective, I first try to split my main file into subfiles by bock to get something like

  • file-1
  • file-2
  • file-3

Then I plan to check each file and if then contains the searched string then I append them back to my new main file.

I don’t know if it’s the best approach to be honest, moreover that I got more than 1600 blocks for 30139 lines in my main file so that’s a lot to parse.

However if I keep this way to do the job, I still have an issue with my code :

#!/bin/ksh
i=0
while IFS=| read -r "line"; do
        if [ `echo $line | grep '/* ------' | wc -l` -eq 1 ]; then
                i=$((i+1))
        fi
        echo $line > "file-$i"
done < $1

As each block are separated by /* --------, if I do an echo $line, the output will be my root directory (/etc, /tmp etc) and not the $line itself.

So I’m aware that this is a 2 questions-post but because the second problem can be bypassed using a different way doing the script, it is definitely linked.

EDIT :

The solution has to be in korn shell as I cannot install anything on this machine

Advertisement

Answer

When you really want to use a while read construction, try avoiding additional files and system calls.

matched=0
all=
while IFS= read -r line; do
  if [[ ${line} =~ "/* ----"* ]]; then
      if [ ${matched} -eq 1 ]; then
         printf "%sn" "${all}"
      fi
      all=
      matched=0
  fi
  all="${all}${line}
"
  if [[ "${line}" =~ line ]]; then
    matched=1
  fi
done < <(cat mainfile; echo "/* ---- The End --- */" )
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement