여러 줄에서 패턴 추출

여러 줄에서 패턴 추출

test.tex다음과 비슷한 내용의 파일이 있습니다 .

\documentclass{scrartcl}
\usepackage{graphicx}
\title{Test}
\author{Author 1, Author 2, Author 3}
\begin{document}
\end{document}

에 작성된 모든 저자를 추출하고 싶습니다 { ... }. 그래서 나는 다음을 수행했습니다.

authors=$(cat test.tex | grep '\author' | tr -d '\author' | tr -d '{' | tr -d '}' )

이 코드는 이 경우에만 작동합니다. 내 질문은

  1. []대신 있을 수도 있어요{}
  2. 아래 예와 같이 한 줄은 여러 줄에 걸쳐 있을 수 있습니다.

\author{Author 1,

Author 2,

Author 3}

이 두 가지 문제를 해결하는 방법을 아는 사람이 있습니까?

답변1

grep -zPo '\\author{\K[^}]*' ex1.tex | tr '\0\n' '\n '

몇 가지 간단한 설명:

  • -z입력 및 출력 레코드("행")는 NULL( )로 구분됩니다 \0. 따라서 전체 TeX 파일은 하나의 레코드가 됩니다.
  • -PPerl PCRE 정규식 변형을 사용하십시오.
  • -oregExp와 일치하는 레코드 부분만 출력됩니다.
  • \\author{\K왼쪽 컨텍스트를 나타냅니다.

tr '\0\n' '\n ' 출력 레코드 구분 기호를 변경 하고( \0to \n) 이름 내의 줄 바꿈을 제거합니다( \nto )

답변2

#!/bin/bash

sed -nr '
/\\author/ {
    :ending
    /]|}$/! {
        N   
        b ending 
    }
    s/\\author(\{|\[)(.*)(}|])/\2/p
}
' test.tex

설명(동일한 코드이지만 주석이 추가됨):

#!/bin/bash

sed -nr '
# if the line contains the \author string, we are working with it.
/\\author/ {

    ##### this part are needed for multiple line pattern processing

    # put a label here. We will be return to this point, 
    # until we reach line, which have } or ] in the ending.
    :ending

    # if this line does not ended by } or ]. 
    # It is tell us, that this line continues on the next line.
    /]|}$/! {

        # Take the next line and append it to the previous line. 
        # Just join them together.
        N   

        # Go to the ":ending" label
        b ending 
    }

    ##### ending multiple line pattern processing

    # remove the \author word and brackets from line
    s/\\author(\{|\[)(.*)(}|])/\2/p
}
' test.tex

테스트 파일

\documentclass{scrartcl}
\usepackage{graphicx}
\title{Test}
\author{Author 1, Author 2, Author 3}
\author[Author 1, Author 2, Author 3]
\author{Author 1,
Author 2,
Author 3}
\author[Author 1,
Author 2,
Author 3]
\begin{document}
\end{document}

산출

Author 1, Author 2, Author 3
Author 1, Author 2, Author 3
Author 1,
Author 2,
Author 3
Author 1,
Author 2,
Author 3

답변3

이것은 작업을 수행하는 것 같습니다egrep -o '[\[{]?Author' | sed -E 's/[\[{]//'

예:

1)

echo "\documentclass{scrartcl}
\usepackage{graphicx}
\title{Test}
\author[Author 1,
Author 2
Author 3 ] " | egrep -o '[\[{]?Author' | sed -E 's/[\[{]//'
Author
Author
Author

2)

echo "\documentclass{scrartcl}
\usepackage{graphicx}
\title{Test}
\author[Author 1, Author 2, Author 3]
\begin{document}
\end{document}" | egrep -o '[\[{]?Author' | sed -E 's/[\[{]//'
Author
Author
Author

삼)

echo "\documentclass{scrartcl}
\usepackage{graphicx}
\title{Test}
\author{Author 1, Author 2, Author 3}
\begin{document}
\end{document}" | egrep -o '[\[{]?Author' | sed -E 's/[\[{]//'
Author
Author
Author

grep아마도 LookBehind와 같은 것을 사용하여 이 작업을 수행 할 수 있을 것입니다 . 저는 개인적으로 sed아무런 문제 없이 after 에 파이프를 사용합니다 grep.

답변4

파이썬

질문에 제공된 입력 파일을 사용하면 다음과 같이 라이너를 수행할 수 있습니다.

$ python -c 'import sys,re;f=open(sys.argv[1],"r");a=tuple(l for l in f.readlines() if l.startswith("\\author") );print("\n".join(re.split(", |,|{|}",a[0].strip())[1:]))' input.tex      
Author 1
Author 2
Author 3

그리고 스크립트는 다음과 같습니다:

#!/usr/bin/env python

import sys,re

# read the doc, find the desired line
line=""
with open(sys.argv[1]) as f:
    for l in f:
        if l.startswith("\\author"):
            line=l.strip()
            break
# split at multiple separators, get slice of that list starting since 2nd item
author_list = re.split( ", |,|{|}", line )[1:] 
# print 1 author per line
print("\n".join(author_list))

두 가지 주요 단계가 있습니다. 파일을 읽고 string 으로 시작하는 줄을 찾은 \\authors다음 여러 구분 기호로 줄을 토큰 목록으로 분할하고 해당 토큰 목록에서 개행으로 구분된 문자열을 작성합니다. 나는 또한 ,당신이 또는 에서 분할해야 할 가능성을 고려해 보았습니다 ,<space>.

관련 정보