4

Hi I would like to write some program to format random another script-code. You have a testdata.sh code in a form like:

#!/bin/sh
# usage: fsplit file1 file2
total=0; lost=0
while
    read next
do
total=`expr $total + 1`
for i in *; do
if test -d $dir/$i
then
cd $dir/$i
while echo "$i:" ; read x ; do eval $x ; done
cd ..
fi
done
case "$next" in
*[A-Za-z]*)  echo "$next" >> $1 ;;
*[0-9]*)     echo "$next" >> $2 ;; *)           lost=`expr $lost + 1`
esac
done ; echo "$total lines read, $lost thrown away"

You call your script "format_it.sh" ...

 sh format_it.sh -t < testdata.sh

which mean to use tabulators for formatting. Otherwise you can use

 sh format_it.sh -s5 < testdata.sh

which means f.e. to use 5spaces for formatting.

What I want to do, is to format it in this way. Always after while/for/case/if.

#!/bin/sh
# usage: fsplit file1 file2
total=0; lost=0
     while
          read next
          do 
          total=`expr $total + 1`
               for i in *; do
                    if test -d $dir/$i
                         then
                         cd $dir/$i
                              while echo "$i:" ; read x ; do eval $x ; done
                         cd ..
                    fi
               done
           case "$next" in 
                *[A-Za-z]*)  echo "$next" >> $1 ;;
                *[0-9]*)     echo "$next" >> $2 ;; 
                *)           lost=`expr $lost + 1`
           esac
     done ;
 echo "$total lines read, $lost thrown away"

Till now my script looks like that..

#!/bin/sh

function use_t(){
layer=0

while read a; do
     if [ -n "$(echo $a | egrep "if|case|while|for")" ]; then
          layer=$((layer+1))
          sed -r  "s#(if|case|while|for)#\n awk "BEGIN \{ ORS=\"\"; for (i=0;i<=$layer;i++)    
          print \"\t\" \}" \1 #g"

          elif [ -n "$(echo $a | egrep "fi|esac|done")" ]; then layer=$(layer-1)) 
      fi
 done
}


if [ "$1" = "-t" ] ; then
use_t
elif [ -n "$(echo "$1" | grep  "^\-s[1-9][0-9]*$")" ] ; then
n_spaces=$(echo $1| sed 's/'-s'//' )
#use_s 
else
   echo "ERROR -  wrong input of parameters"
fi

The problem line is :

sed -r  "s#(if|case|while|for)#\n awk "BEGIN \{ ORS=\"\"; for (i=0;i<=$layer;i++)    
print \"\t\" \}" \1 #g"

What I want this line do, is to for every if/case/while/for in a text replace it with a /n {to get it to new line) and then use "layer times" tab/space to have it nice formatted. I dont know how to make this line with sed/awk work. Advices?

Maybe you see another way to do it as well, I would be glad for some tips.

2 Answers 2

2

The only information you need to store is depth of current block of code.

Choose some character and add it to sed 'memory' when you enter new block (e.g. begin|do|...) and remove one when you exit block (e.g. end|done|...). At the beginning of each line add spaces according to size of the memory - you can achieve it by moving characters one by one to the second memory.

But I recommend using either awk or bash as they are much more appropriate.

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

Comments

1

You need a parser that understands the language to do this, you can't do it reliably with a simple script. Google "shell script beautifier" and you'll find a few tools that claim to do it. MAYBE the C beautifiers "indent" or "cb" would even work for a shell script but I doubt it.

Comments

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.