0

and print the number of dots (or any random characters) representing the depth at the beginning of each line the shell script should have 3 parameters. The first is character c, the second is the number of characters per level n, the third is the input file. The script should replace leading spaces with with k*n characters c where k is the level of bracket nesting.

a ( b 
     c d [ e ] f [
  g h { j (
            k ) } l m
     n ] o ) p
q r
would be modified as follows if the script is run with parameters c='.' and n=1:
a ( b
.c d [ e ] f [
..g h { j (
....k ) } l m
..n ] o ) p
q r

Here is my attempt:

c=$1

sed 's|^[[:blank:]]*||g' $3

curr=0
next=0

nb=0
n=$2
makeIndent() {
        local indentChar=$1
        local num=$2
        printf '%*s' "$num" | tr ' ' "$indentChar"
}
while read -r line; do
        for char in '(' '[' '{'; do
                nb=$((curr+1))
                next=$((next+nb))
        done

        for char in ')'']' '}'; do
                nb=$((curr-1))
                next=$((next-nb))
        done
        n=$(($n*$curr))
        indentString=$(makeIndent "$c" "$n")
        curr=$next
        n=$2
        echo "$indentString$line"
done < $3

How can I delete the leading spaces without printing something like this?

a(b
c d[ e]f [
g h { j (
k)}l m
n ]o )p
q r

and the next thing it prints is (with c is '.' and n is 1)

a(b
.....c d[ e]f [
...............g h { j (
...................................k)}l m
...........................................................................n ]o )p

that means the last line was deleted. How can I keep the last line as original? And the counting part is wrong. So I tried to find some ways to count the depth such as creating a count function and change the for loop a little bit

count() {
        local a=$1
        local file=$2
        awk -F\$a '{ print NF-1 }' $file
}
 for char in '(' '[' '{'; do
                nb=$(count "$char" "$3")
                next=$((next+nb))
        done

        for char in ')'']' '}'; do
                nb=$(count "$char" "$3")
                next=$((next-nb))
        done

It turns out to be even worse.

  • all types of brackets are considered (e.g. '(' '[' '{') and they are all well-paired – user350473 May 20 '19 at 18:23
  • Are you asking us to do your homework ? You had a pretty similar question there : unix.stackexchange.com/questions/517707/…, with the very same example and you copy-pasted code from there too... – Httqm May 21 '19 at 10:27
0

I have figured out the solution.

#!/bin/sh

c=$1
curr=0
n=$2
filename=$3
deletespaces() {
        local line=$1
        echo "${line}" | sed -e 's/^[ \t]*//'
}
printchar() {
        local indentChar=$1
        local num=$2
        v=$(printf '%*s' $num "" | tr ' ' "$indentChar")
        echo "$v"
}
counto() {
        local l=$1
        grep -o "[[|{|(]" <<<"$l" | wc -l
}

countc() {
        local l=$1
        grep -o "[]|}|)]" <<<"$l" | wc -l
}
while read -r line; do
        n=$((n*$curr))
        indentString=$(deletespaces "$line")
        printCharr=$(printchar "$c" "$n")
        echo "$printCharr$indentString"

        o=$(counto "$line")
        curr=$(( $curr + $o ))

        cl=$(countc "$line")
        curr=$(( $curr - $cl ))
        n=$2
done < "$filename"

basically what I did for each line is to delete the leading spaces, and count the depth of brackets for each first letter of each line (in particular, increase 1 if encountering 1 open bracket, decrease 1 if it's a closing bracket and then store the value into variable curr, which represents the number of the input character in the next line). By the way, n is a random input number. Since the main task is to print k*n (k is curr, the depth of brackets) characters so n should be constant. That's why I reset n=$2 in the end of the while loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy