여러 줄에 걸쳐 있더라도 괄호 사이에 있는 내용을 바꾸세요.

여러 줄에 걸쳐 있더라도 괄호 사이에 있는 내용을 바꾸세요.

Bash 또는 쉘 스크립트를 사용하고 교체하고 싶습니다아무것두 괄호 사이에 공백이 있습니다. 두 괄호 사이의 텍스트는 여러 줄이 될 수 있습니다. 예를 들면 다음과 같습니다.

myFunction (line0

line1

line2

line3

line4) 

다음으로 변환하고 싶습니다.

myFunction ( )

답변1

@Serg의 답변을 받아 bash한 줄에 2~3개의 프로세스 대신 bash 내장 기능을 사용하도록 변환하세요. 이 과정은 저렴하지만 무료는 아닙니다!

#!/bin/bash
# Use shell builtins, read, true, false, printf
flag=false
while IFS= read -r line
do
    case "$line" in
    (*"("*) flag=true ;;
    esac

    if $flag
    then
        line=${line//line/newline} 
    fi

    printf "%s\n" "$line"

    case "$line" in
    (*")"*) flag=false ;;
    esac

done < "$1"

답변2

AWK

{}AWK를 사용하면 다양한 조건에서 코드 블록을 실행할 수 있습니다. 이 경우에는 gsub()Contains (에서 Contains 까지 의 행 범위에서 각 행을 실행하려고 합니다 ).

$ awk '$0~/[(]/,$0~/[)]/{gsub(/line/,"newline")};1' input.txt                                                     
another line
something else

myFunction (newline0

newline1

whatever

newline2

newline3

newline4)

some other line

Python (원래 답변)

다음은 작업을 수행하는 빠른 Python 스크립트입니다.

#!/usr/bin/env python3
from __future__ import print_function
import sys

with open(sys.argv[1]) as fp:
    flag = None
    for line in fp:
        clean_line = line.strip()
        if "(" in clean_line: flag = True
        if flag:
           clean_line = clean_line.replace("line","newline")
        print(clean_line) 
        if ")" in clean_line: flag = False

테스트 실행:

$ cat input.txt                                                                                                          
another line
something else

myFunction (line0

line1

lilne2

line3

line4)

some other line
$ ./edit_function_args.py input.txt                                                                                      
another line
something else

myFunction (newline0

newline1

newline2

newline3

line4)

some other line

배쉬 버전

bash다음 과 같이 다시 작성된 것을 제외하고 동일한 스크립트sed

#!/bin/bash
flag=false
while IFS= read -r line
do

    if grep -q '('  <<< "$line"
    then
        flag=true 
    fi


    if $flag
    then
        line=$(sed 's/line/newline/'   <<< "$line") 
    fi

    printf "%s\n" "$line"


    if grep -q ')'  <<< "$line"
    then
        flag=false     
    fi

done < "$1"

답변3

perl해결 방법이 괜찮고 파일이 전체적으로 처리될 만큼 작은 경우 :

$ perl -0777 -pe 's/\([^)]+\)/$&=~s|line|newline|gr/ge' ip.txt    
myFunction (newline0

newline1

newline2

newline3

newline4) 
  • -0777전체 입력 파일을 먹어라
  • \([^)]+\)일치시킬 패턴 - 문자 (가 아닌 문자가 오고 )다음으로 끝납니다.)
  • $&=~s|line|newline|gr인용된 패턴이 여기에서 사용되며 $&필요한 대체(줄 바꾸기에서 줄 바꿈)가 수행됩니다. r결과를 대체 문자열로 반환하는 플래그에 유의하세요.
  • e플래그를 사용하면 문자열 대신 표현식을 사용할 수 있습니다.
  • perl -i -0777 -pe내부 편집 용

답변4

사용 awk:
awk '
  function mysub(str) {
    if (str) gsub(/line/, "newline", str); return str
  }
  BEGIN {
    OFS=FS="("
  }
  NF>1 {
    if (FS=="(") {
      print $1,mysub($2); OFS=FS=")"
    } else {
      print mysub($1),$2; OFS=FS="("
    }
    next
  }
  {
    print FS=="(" ? $0 : mysub($0)
  }' /path/to/input

사용자 정의 함수는 mysub대괄호 사이에 필요한 대체를 수행하는 곳입니다. 대괄호가 중첩되지 않았다고 가정합니다.

작동 방식:

괄호 내부와 외부 괄호의 두 가지 상태가 있습니다.

  • 외부적으로(시작 상태) 입력 및 출력 구분 기호는 왼쪽 대괄호( OFS=FS="(")로 설정됩니다.
  • 입력 구분 기호( )로 NF>1구분된 여러 필드가 포함된 줄을 만나면...
    • ...현재 외부 모드( )에 있으며 FS=="("필드 구분 기호 앞과 뒤의 모든 내용이 출력되지만(출력 구분 기호는 중간에 있음) 후자는 대체 기능( mysub($2))을 거쳐 모드와 출력 구분 기호를 뒤집습니다. 입력 기호( OFS=FS=")")를 변경하여,
    • ...그렇지 않으면( else) 내부 모드에 있고 필드 구분 기호 전후의 모든 내용이 출력되지만 이번에는 전자가 대체 기능( mysub($1))을 거치고 여기에서도 모드가 반전됩니다.
  • 다른 모든 라인에서 외부( )이면 전체 라인이 변경되지 않고 출력되고, FS=="("그렇지 않으면 대체 함수( )를 통해 전체적으로 전달됩니다 mysub($0).
한 줄로 요약하면 다음과 같습니다.
awk 'function m(s){gsub(/line/,"newline",s);return s}BEGIN{OFS=FS="("}NF>1{if(FS=="("){print $1,m($2);OFS=FS=")"}else{print m($1),$2;OFS=FS="("}next}{print FS=="("?$0:m($0)}' /path/to/input
내 까다로운 테스트 데이터(여기서 일부 한 줄 솔루션은 실패함):
line96
line97 myFunction (line0

line1

line2

line3

line4) line98
line99
출력:
line96
line97 myFunction (newline0

newline1

newline2

newline3

newline4) line98
line99
대괄호 사이의 모든 내용을 제거하는 변형입니다(첫 번째 줄과 마지막 줄 바꿈 제외):
awk '
  BEGIN {
    OFS=FS="("
  }
  NF>1 {
    if (FS=="(") {
      print $1,""; OFS=FS=")"
    } else {
      print "",$2; OFS=FS="("
    }
    next
  }
  FS=="("' /path/to/input
이 출력은 다음과 같습니다.
line96
line97 myFunction (
) line98
line99

관련 정보