텍스트 파일에서 다양한 모드로 기호 변경

텍스트 파일에서 다양한 모드로 기호 변경

텍스트 파일이 있습니다. 이는 다음과 같은 일부 패턴을 포함하는 큰 텍스트 파일입니다.

(1), (3), (1,2,3), (1,2,3,4,5,6,7,8,9)

...이와 같이,

(Fig1) (Fig1,Fig2), (Table-1, Table-2) etc.

나는 이런 출력을 원한다

[1], [3], [1,2,3], [1,2,3,4,5,6,7,8,9], (Fig1) (Fig1,Fig2), (Table-1, Table-2)

내 말은 ()를 숫자만 포함하는 []로 변경하고 싶다는 뜻입니다. 도와주세요

답변1

그리고 sed:

sed 's/(\([0-9,]*\))/[\1]/g' filename.txt

[0-9,]*숫자와 쉼표의 개수에 관계없이 일치하는 정규 표현식입니다. \(\)\1슬래시가 없는 간단한 대괄호는 그 자체를 나타냅니다 . [](대체 문자열에는 특별한 의미가 없음) 로 대체됩니다 .

답변2

Python 3 스크립팅 솔루션

아래 스크립트는 정규식을 사용하지 않는 보다 명시적인 "수동" 솔루션이지만 이 작업을 수행할 때 고려해야 할 몇 가지 추가 고려 사항이 있습니다. 이 작업의 핵심은 스크립트가 명령줄에서 제공하는 모든 파일을 읽고 각 줄의 각 문자를 반복하면서 괄호를 찾는 것입니다. 괄호가 보이면 안에 내용을 기록한 다음 쉼표를 버리고 이것이 숫자 문자열인지 판단합니다. 숫자 문자열인 경우 기록된 항목은 단어 목록으로 들어가고 나중에 구분 기호가 있는 함수를 사용하여 .join()한 줄로 재구성됩니다 ", ". 매우 솔직해요.

 #!/usr/bin/env python3
import sys

with open(sys.argv[1]) as fd:
    for line in fd:
        # we're going to store everything into list of words
        # and record individual characters into 'item' string
        # and rebuild everything as we go.
        words = []
        item_found = False
        item = ""
        counter = 0
        for char in line:
            # if we see ( or [ we start recording chars
            # difference is that [ means item already been edited
            # so no need to do anything - just put it into words list
            # as is
            if char == "(" or char == "[":
                item_found = True
                counter = counter + 1
                continue

            if char == ")":
                item_found = False
                if item.replace(",","").isdigit():
                   words.append("[" + item + "]")
                else:
                   words.append("("+item+")")
                item = ""

            if char == "]":
              item_found = False
              item = item + char
              words.append("[" + item) 
              item = ""

            if item_found:
                item = item + char

        # if we didn't see any open brackets or no closing brackets
        # just print the line as is - otherwise give us the altered one
        if counter == 0 or item_found:
            print(line.strip())
        else:
            print(", ".join(words))

테스트 실행:

나는 OP의 입력을 자유롭게 사용하여 몇 가지 다른 테스트 사례와 함께 추가 2줄을 포함했습니다.

$ # original input file
$ cat input.txt
(1), (3), (1,2,3), (1,2,3,4,5,6,7,8,9), (Fig1) (Fig1,Fig2), (Table-1, Table-2)
(table-25),[1,2,3],(figure-35)
(figure-1),(figure-2)
$ # script output 
$ ./change_brackets.py input.txt                                                          
[1], [3], [1,2,3], [1,2,3,4,5,6,7,8,9], (Fig1), (Fig1,Fig2), (Table-1, Table-2)
(table-25), [1,2,3], (figure-35)
(figure-1), (figure-2)

40,000줄의 텍스트에 대해 매우 빠르게 수행됩니다.

$ wc -l big_input.txt                                                                     
40000 big_input.txt
$ time ./change_brackets.py big_input.txt  > /dev/null                                    
    0m01.64s real     0m01.60s user     0m00.01s system

가능한 개선을 위한 제안(및스티븐이 언급한 것 중 하나를 다루기)는 if item.replace(",","").isdigit()행을 로 변경하는 것입니다 if item.replace(",","").replace(".","").isdigit(). 이렇게 하면 부동 소수점 숫자(예: 3.1415)를 처리할 수도 있습니다.

긴? 예. 분명한? 예. 효과적인가요? 예.

답변3

sed -E 's/[(](([0-9]+,?)+)[)]/[\1]/g'

sed -e 's/(\(\([0-9]\{1,\},\{0,\}\)\{1,\}\))/[\1]/g'

( 및 ) 대괄호로 둘러싸인 정규식 [0-9]+,?가 한 번 이상 동시에 발생하는 경우를 찾습니다. 성공하면 바깥쪽 괄호가 [ ]로 변경됩니다.

두 번째 sed 문은 위 명령문의 POSIXly 버전입니다.

관련 정보