grep: 닫는 괄호를 찾는 방법은 무엇입니까?

grep: 닫는 괄호를 찾는 방법은 무엇입니까?

한 부분은 내가 찾고자 하는 줄 번호로 /usr/share/X11/xkb/symbols/us시작 하고 끝납니다 xkb_symbols "dvorak" {.};

partial alphanumeric_keys
xkb_symbols "dvorak" {

    name[Group1]= "English (Dvorak)";

    key <TLDE> { [       grave, asciitilde, dead_grave, dead_tilde      ] };

    key <AE01> { [          1,  exclam          ]       };
    key <AE02> { [          2,  at              ]       };
    key <AE03> { [          3,  numbersign      ]       };
    key <AE04> { [          4,  dollar          ]       };
    key <AE05> { [          5,  percent         ]       };
    key <AE06> { [          6,  asciicircum, dead_circumflex, dead_circumflex ] };
    key <AE07> { [          7,  ampersand       ]       };
    key <AE08> { [          8,  asterisk        ]       };
    key <AE09> { [          9,  parenleft,  dead_grave] };
    key <AE10> { [          0,  parenright      ]       };
    key <AE11> { [ bracketleft, braceleft       ]       };
    key <AE12> { [ bracketright, braceright,  dead_tilde] };

    key <AD01> { [  apostrophe, quotedbl, dead_acute, dead_diaeresis    ] };
    key <AD02> { [      comma,  less,   dead_cedilla, dead_caron        ] };
    key <AD03> { [      period, greater, dead_abovedot, periodcentered  ] };
    key <AD04> { [          p,  P               ]       };
    key <AD05> { [          y,  Y               ]       };
    key <AD06> { [          f,  F               ]       };
    key <AD07> { [          g,  G               ]       };
    key <AD08> { [          c,  C               ]       };
    key <AD09> { [          r,  R               ]       };
    key <AD10> { [          l,  L               ]       };
    key <AD11> { [      slash,  question        ]       };
    key <AD12> { [      equal,  plus            ]       };

    key <AC01> { [          a,  A, adiaeresis, Adiaeresis ]     };
    key <AC02> { [          o,  O               ]       };
    key <AC03> { [          e,  E               ]       };
    key <AC04> { [          u,  U               ]       };
    key <AC05> { [          i,  I               ]       };
    key <AC06> { [          d,  D               ]       };
    key <AC07> { [          h,  H               ]       };
    key <AC08> { [          t,  T               ]       };
    key <AC09> { [          n,  N               ]       };
    key <AC10> { [          s,  S               ]       };
    key <AC11> { [      minus,  underscore      ]       };

    key <AB01> { [   semicolon, colon, dead_ogonek, dead_doubleacute ] };
    key <AB02> { [          q,  Q               ]       };
    key <AB03> { [          j,  J               ]       };
    key <AB04> { [          k,  K               ]       };
    key <AB05> { [          x,  X               ]       };
    key <AB06> { [          b,  B               ]       };
    key <AB07> { [          m,  M               ]       };
    key <AB08> { [          w,  W               ]       };
    key <AB09> { [          v,  V               ]       };
    key <AB10> { [          z,  Z               ]       };

    key <BKSL> { [  backslash,  bar             ]       };
};

192를 반환하는 환경의 시작을 찾을 수 있습니다.

grep -n 'xkb_symbols "dvorak"' /usr/share/X11/xkb/symbols/us | cut -d ":" -f1 > /tmp/lineNumberStartEnvironment

그렇게 했지만 출력이 비어 있습니다.

# http://unix.stackexchange.com/a/147664/16920
grep -zPo 'pin\(ABC\) (\{([^{}]++|(?1))*\})' /usr/share/X11/xkb/symbols/us

의사코드

  1. 먼저 file 에 지정된 줄 번호로 이동합니다 /tmp/lineNumberStartEnvironment.
  2. 줄 내용에 있는 닫는 괄호를 찾으세요 /tmp/lineNumberStartEnvironment.
    • 전체 파일뿐만 아니라 본문의 데이터 내용에도 이 작업을 수행합니다./usr/share/X11/xkb/symbols/us

다음 줄까지 heredoc를 사용해 보세요. [cas, Kusalananda]

내가 하고 있는 일은 구분 기호에 무엇을 넣어야 할지 모르겠습니다. -n또한 공백이 반환됩니다.

sed -n -f - /usr/share/X11/xkb/symbols/us <<END_SED | cut -f1
/xkb_symbols "dvorak" {/,/^};/{
        /xkb_symbols "dvorak" {/=
        /^};/=
}
END_SED

그러나 출력은 비어 있습니다.

시스템: 우분투 16.04
Grep: 2.25

답변1

이 스크립트는 해당 줄에서 다음 줄까지의 범위에서 일치하는 줄의 줄 번호를 인쇄합니다 sed(이것은 우리가 얻은 줄 번호와 동일합니다)./^};//xkb_symbols "dvorak" {//^};/};

/xkb_symbols "dvorak" {/,/^};/{
        /^};/=
}

시작 및 끝 줄 번호가 필요한 경우:

/xkb_symbols "dvorak" {/,/^};/{
        /xkb_symbols "dvorak" {/=
        /^};/=
}

$ sed -n -f tiny_script.sed /usr/share/X11/xkb/symbols/us
192
248

또는:

$ sed -n -f - /usr/share/X11/xkb/symbols/us <<END_SED
/xkb_symbols "dvorak" {/,/^};/{
        /xkb_symbols "dvorak" {/=
        /^};/=
}
END_SED

편집하다: Bash를 사용한다고 가정하고 변수에서 이 두 숫자를 얻으려면 다음을 수행하십시오.

pos=( $( sed -n -f - /usr/share/X11/xkb/symbols/us <<END_SED
        /xkb_symbols "dvorak" {/,/^};/{
                /xkb_symbols "dvorak" {/=
                /^};/=
        }
END_SED
) )

echo "start = " ${pos[0]}
echo "end   = " ${pos[1]}

그리고 안녕! 또 다른 Dvořák 사용자입니다!

답변2

#! /usr/bin/awk -f

/"dvorak"/ {dvorak++};

/{/ && dvorak {b++} ;

/}/ && dvorak {b--} ;

dvorak && b == 0 && NR > 1 {
    print NR;
    exit
}

$ ./find-dvorak.awk /usr/share/X11/xkb/symbols/us
248

b이것은 여는 중괄호가 보일 때마다 증가 {하고 닫는 중괄호가 보일 때마다 감소되는 카운터()를 사용합니다 }. 또한 dvorak"dvorak" 섹션 내에 있는지 확인하기 위해 플래그 변수( )를 사용합니다 .

b == 0이고 줄 번호가 1보다 큰 경우 줄 번호를 인쇄합니다.

실수: 주석 처리된 괄호나 문자열에 포함된 괄호는 고려되지 않습니다.

여는 괄호와 닫는 괄호의 줄 번호를 원하는 경우:

#! /usr/bin/awk -f

/"dvorak"/ {dvorak++};

/{/ && dvorak {
    b++;
    if (!first++) {
        print NR
    }
} ;

/}/ && dvorak {b--} ;

dvorak && b == 0 && NR > 1 {
    print NR;
    exit
}

$ ./find-dvorak2.awk /usr/share/X11/xkb/symbols/us
192
248

다음은 xkb_symbols모든 섹션을 검색할 수 있는 버전입니다.

#! /usr/bin/awk -f

match($0,"xkb_symbols.*\""search"\"")  {found++};

/{/ && found {
    b++;
    if (!first++) {
        print NR
    }
} ;

/}/ && found {b--} ;

found && b == 0 && NR > 1 {
    print NR;
    exit
}

$ ./find-xkb_symbols.awk -v search=dvorak-intl /usr/share/X11/xkb/symbols/us
255
314

관련 정보