テキストファイル内の1行にネストされた括弧の深さを探しますか?

テキストファイル内の1行にネストされた括弧の深さを探しますか?

そして、各行の先頭に深さを表す点(または任意の文字)数を印刷します。シェルスクリプトには3つのパラメータが必要です。 1 番目は文字 c、2 番目はレベル n あたりの文字数、3 番目は入力ファイルです。スクリプトは先行スペースをk * n文字cに置き換える必要があります。ここで、kは角かっこ入れ子レベルです。

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

私の試みは次のとおりです。

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

このようなものを印刷せずに先行スペースを削除するにはどうすればよいですか?

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

次に印刷されるのは(cは「.」、nは1)です。

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

これは最後の行が削除されることを意味します。最後の行をそのままにするにはどうすればよいですか?そして計算部分が間違っていますね。そのため、計算関数を作成し、forループを少し変更するなど、深さを計算する方法を見つけようとしました。

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

状況はさらに悪かった。

ベストアンサー1

解決策を見つけました。

#!/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"

基本的に、各行に対して私がすることは、先行スペースを削除し、各行の各最初の文字の角かっこ深さを計算することです(具体的には、左角かっこが1つある場合は1だけ増やし、右角括弧に出会うと1ずつ増やしてから行1 つずつ入力し、次の行に入力される文字数を示す変数 curr に値を格納します。 n は任意に入力された数値です。なので、nは定数でなければなりません。

おすすめ記事