Поиск строк с нечетным количеством фигурных скобок - PullRequest
1 голос
/ 03 февраля 2012

У меня есть документ, содержащий { и }, но я обнаружил, что есть ошибки. Я использовал grep -c { * и grep -c } *, чтобы найти, что число { и } не равно. Я хочу найти эти строки с возможными ошибками, чтобы проверить их вручную.

  • Закрывающие скобки всегда должны появляться на одной строке, поэтому мне нужно найти строки с {, у которых нет закрывающей }, или строки с } без открывающей скобки.
  • Некоторые строки имеют много скобок, например { } { } { }.
  • Никогда не должно быть вложенных скобок, например `{{{}}} '.

Как мне искать строки, которые не имеют правильного количества фигурных скобок?

Ответы [ 4 ]

3 голосов
/ 03 февраля 2012

Вы можете сделать что-то вроде этого (Это напечатает строку и номер строки) -

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

Тест:

[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 {
2 голосов
/ 03 февраля 2012

Это может работать для вас:

sed 'h;y/}/{/;s/[^{]*{[^{]*{[^{]*//g;/./!d;g file
1 голос
/ 03 февраля 2012

Я не за компьютером, чтобы попробовать, но я думаю, что это может сработать

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

Если я написал правильно, это должно совпадать (поэтому не печатать, потому что -v) только строки, где вся строка состоит из пар, таких что

  1. Первая скобка - это открывающая скобка, а
  2. Следующая скобка существует и является закрывающей скобкой,

Повторяется ноль или более раз.

1 голос
/ 03 февраля 2012

Попробуйте этот код.Он напечатает те строки, для которых количество фигурных скобок не совпадает

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