Village
Village

Reputation: 24453

Finding lines with an odd number of braces

I have a document containing { and } throughout, but I found there are mistakes. I used grep -c { * and grep -c } * to find that the number of { and } is not equal. I want to find those lines with possible errors, so I can manually check them.

How can I search for lines that do not have the correct number of braces?

Upvotes: 1

Views: 276

Answers (4)

potong
potong

Reputation: 58548

This might work for you:

sed 'h;y/}/{/;s/[^{]*{[^{]*{[^{]*//g;/./!d;g file

Upvotes: 2

Kevin
Kevin

Reputation: 56129

I'm not at my computer to try, but I think this might work

grep -v '^\([^{}]*{[^{}]*}[^{}]*\)*$'

If I've written it correctly, this should match (so not print, because of the -v) only lines where the entire line consists of pairs such that

  1. The first brace is an opening brace, and
  2. The next brace exists and is a closing brace,

Repeated zero or more times.

Upvotes: 1

jaypal singh
jaypal singh

Reputation: 77175

You can do something like this (This will print the line and the line number) -

gawk -v FS="" '
{cnt=0;for(i=1;i<=NF;i++) if ($i=="{") ++cnt ;
else if ($i=="}") --cnt; if (cnt!=0) print NR":"$0}' file

Test:

[jaypal:~/Temp] cat file
this is {random text} some with { some without
purpose is{ to identify such lines} where { dont have a matching }
and print those lines with just one {

[jaypal:~/Temp] gawk -v FS="" '
> {cnt=0;for(i=1;i<=NF;i++) if ($i=="{") ++cnt ;
> else if ($i=="}") --cnt; if (cnt!=0) print NR":"$0}' file
1:this is {random text} some with { some without
3:and print those lines with just one {

Upvotes: 3

Raghuram
Raghuram

Reputation: 3967

Try this code. It will print those lines for which the brace count dosen't match

#!/bin/bash
LINE_COUNT=1
cat decrypt.txt | while read line
do
    i=0
    O_B=0
    C_B=0
    while (( i++ < ${#line} ))
    do
       char=$(expr substr "$line" $i 1)
       #echo $char
       if [ "$char" = "{" ]
       then
        O_B=`expr $O_B + 1`
       elif [ "$char" = "}" ]
       then
        C_B=`expr $C_B + 1`
       fi
    done
    #echo "$line|$O_B|$C_B"
    if [ $O_B -ne $C_B ]
    then
        echo "$LINE_COUNT|$line|$O_B|$C_B"
    fi
    LINE_COUNT=`expr $LINE_COUNT + 1`
done

Upvotes: 1

Related Questions