Okay, so you can use variable substitution to slice up the variables in the current shell, i.e. you don't need to call cut etc.
If you know the field lengths are fixed, then perhaps something like this will work:-
c=0
while read record
do
((c=$c+1)) # Increment record counter
remainder="${record#?????}" # 5x? to cut off first five characters
p1="${record%${remainder}}" # Get the first part of the record dropping the remainder
record="${remainder}"
remainder="${record#??}" # 2x? to cut off first two characters
p2="${record%${remainder}}" # Get the next part of the record dropping the remainder
record="${remainder}"
remainder="${record#????}" # 4x? to cut off first four characters
p3="${record%${remainder}}" # Get the next part of the record dropping the remainder
record="${remainder}"
remainder="${record#???????}" # 7x? to cut off first seven characters
p4="${record%${remainder}}" # Get the next part of the record dropping the remainder
record="${remainder}"
remainder="${record#??}" # 2x? to try to cut off first two characters
if [ "${remainder" = "${record}" ]
then
p5="${record}" # Use the whole of the remaining record if there are no other characters
else
printf "Error line %d\n" "${c}" >&2 # Write to standard error
fi
printf "%s;%s;%s;%s;%s\n" "$p1" "$p2" "$p3" "$p4" "$p5"
done < in_file > out_file 2> err_file
Does that sort of structure help? There may be a neater way in awk to read and split the record and I'd be happy to learn.