안녕하세요. 정규식에 대해 질문드리고 싶습니다.

익명 사용자의 이미지

시스템 공부를 시작한지 얼마 안된 학생입니다.
grep 명령에서 사용할 정규식을 구성하고 싶은데, 정규식이 처음이다 보니 어렵네요... 도움 부탁드립니다.

...
 
atomic64_set(...);
 
printk("test....");
 
a1 = kmalloc(0x30);
 
memset(a1, a2, a3);
 
...

예를 들어 위와 같은 코드가 있을 때, printk 함수부터 memset 까지의 함수 부분을 grep 할 수 있는 정규식을 짜고 싶습니다.

printk("test....");
 
a1 = kmalloc(0x30);
 
memset(a1, a2, a3);

위와 같이 출력이 되는 것처럼요.

제 짧은 경험으로는 정규식을 작성했을 때 하나의 행에 대한 결과만 출력이 되고, 위 예제와 같이 여러 행으로 구성된 pattern을 출력하는 정규식 작성이 어렵네요..

어떻게 작성하면 좋을지 도움 부탁드립니다.

chanik의 이미지

grep에서 아래와 같이 하면 비슷하게 나오겠지만, 여러 줄에 걸쳐 정규식이 적용되게 하느라 newline 대신 NULL 문자를 줄끝문자로 취급하므로 원본의 줄단위로 결과를 보여주지는 못합니다. (그나마 이 방식도 GNU grep 2.20에서는 안 되고 3.4에서는 되네요)

$ grep -zo "printf.*memset" sample.c

아마 grep을 더 잘 써서 해결할 방법도 있겠으나, 그냥 아래와 같이 sed나 awk를 쓰는 방법도 있습니다.

$ sed -n -e '/printf/,/memset/' sample.c
$ awk '/printf/,/memset/' sample.c

조건을 줄 때 /printf/ 처럼 단순문자열이 아닌 /^printf/ 또는 /printf.*test/ 식으로 상황에 따라 대상을 더 좁게 특정할 수도 있습니다.
익명 사용자의 이미지

큰 도움이 되었습니다.

익명 사용자의 이미지

혹시 말씀해주신 대로 grep 을 사용하여 위와 같은 패턴을 사용하면, 패턴으로 지정한 함수들 사이에 너무 많은 데이터가 들어가게 되는데, 혹시 패턴 검색 라인수를 지정할 수 있는 방법이 있을까요?

printf와 memset 함수 사이에 들어가는 코드를 10줄 까지만 허용한다.. 라는 느낌으로요.

chanik의 이미지

grep multi line regex 정도로 구글 검색하면 글이 꽤 많이 나옵니다.

grep에 -P, --perl-regexp 옵션을 넣으면 정규식 동작이 꽤 달라지는군요.
아래와 같이 하면 printf와 memset 사이에 9줄 이내인 경우까지만 출력될것입니다.
좀 실험해보시고 상황에 맞게 최소값(0)과 최대값(10)을 만져서 쓰시면 되겠습니다.

$ grep -Pzo "printf(.*\n){0,10}.*memset" sample.c

printf 등장 이후 (.*\n)가 printf 줄 포함 0 ~ 10번 이내로 반복되다가 memset이 등장하는 패턴을 찾아 출력하라는 뜻입니다. (.*\n) 내부의 .*\n는 임의의 문자가 0개 이상 반복되다가 newline이 나오는 패턴, 즉 그냥 평범한 한 줄을 말합니다.

printf 등장줄 처음부터 memset 등장줄 끝까지 출력하려면 아래와 같이 하면 되겠고요. 저는 펄의 정규식 잘 모르고, 그냥 구글 참조해서 약간의 실험을 통해 대충 구성한 정규식입니다. 더 아름다운 정규식이 얼마든지 있을 것입니다.

$ grep -Pzo "^.*printf(.*\n){0,10}.*memset.*$" sample.c
chanik의 이미지

awk로 해결하려면 아래와 같이 할 수 있겠습니다. awk를 좋아하는 제 취향때문에 굳이 올립니다만, 코드가 지저분해서 별 쓸모는 없겠네요.

$ awk 'BEGIN{MAX=10} /printf/{idx=0; line[idx]=$0; while(!/memset/){ if(!getline || idx>MAX) next; idx++; line[idx]=$0; } for(i=0;i<=idx;i++) print line[i];}' sample.c

여러 줄로 나눠쓰면 아래와 같고요. MAX 값에 의해 최대 허용 줄수가 정해집니다.

$ awk '
BEGIN{MAX=10} 
/printf/{
  idx=0;
  line[idx]=$0;
  while(!/memset/) {
    if(!getline || idx>MAX) next;
    idx++;
    line[idx]=$0;
  }
  for(i=0;i<=idx;i++) print line[i];
}' sample.c
익명 사용자의 이미지

친절한 답변 감사드립니다. 더 구체적인 것들은 찾아서 공부해보겠습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.