Bash는 두 패턴 사이의 파일에서 여러 줄을 다른 파일의 내용으로 바꾸시겠습니까?

Bash는 두 패턴 사이의 파일에서 여러 줄을 다른 파일의 내용으로 바꾸시겠습니까?

long.js이 콘텐츠가 포함된 긴 자바스크립트 파일이 있습니다.

... more lines

ProcessCoverageController.createExampleQueries = function () {
    return [
        {
            title: '-- Select a query --',
            query: ''
        }, {
            title: 'No encoding',
            query: 'return avg($c)'
        }
    ];
};
ProcessCoverageController.$inject = [
    "$scope",
    "$log",
    "$interval",
    "Notification",
    "rasdaman.WCSService",
    "rasdaman.ErrorHandlingService"
];

... more lines

내가 하고 싶은 일은 의 내용을 다른 파일(예: )의 내용 return [ ... ];으로 바꾸는 것입니다.content.js

return [
        {
            title: 'title1',
            query: `query1 as asdasd asdasd`
        }, {
            title: 'title2',
            query: `query2 asdas dasd asd asda`
        }, {
            title: 'title3',
            query: `query3 asd asdasdasdasdasdasdasd`
        }, {
            title: 'title4',
            query: `query4 3asd asdasda sdasdasdasdasdad`
        }
    ];

누군가 sed나 Perl을 사용하여 이 작업을 수행하는 방법에 대한 힌트를 줄 수 있습니까? (해봤는데 Perl이 sed보다 구현하기 더 쉬운 도구인 것 같습니다.) 그러나 아래 예는 작동하지 않습니다.

#!/bin/bash

file_content=`cat content.js`
perl -i -p0e 's/ProcessCoverageController.createExampleQueries = function.*?ProcessCoverageController.\$inject/$file_content/s' long.js

답변1

이 문제는 다양한 방법으로 해결될 수 있으며 그 중 일부는 아래에 나열되어 있습니다.

참고: /BEGIN/ /END/ 명확하게 보이도록 하기 위해 이것을 선택했습니다. 원하는 테두리 마커로 바꾸십시오.

sed /END/가 마지막 줄에 나타나지 않아야 한다고 가정합니다.

sed -e '
  /BEGIN/,/END/!b
  //!d;/END/!b
  r content.js
  N
' long.js

피복재:

  • 비블록 영역을 있는 그대로 인쇄합니다./BEGIN/,/END/!b
  • 블록 내부에서 구멍을 제거합니다.//!d
  • 블록의 위쪽 테두리를 인쇄합니다./END/!b
  • 출력 버퍼를 content.js 파일의 내용으로 채웁니다. r contents.js여기서는 stdout으로 인쇄하지 않습니다.
  • 다음 줄을 읽고 /END/ 줄에 추가합니다. 읽기 작업은 출력 버퍼 플러시를 트리거합니다. N 명령으로 인해 이 루프에서는 패턴 공간이 인쇄되지 않습니다. 이는 /END/ 행 앞에 content.js 파일의 내용을 배치하는 효과가 있습니다.

awk '
  BEGIN {
    repl = ARGV[1]
    ARGV[1] = ""
  }
  /BEGIN/ && !f {print;f=1}
  /END/ && f {
    while (getline t < repl > 0) {
      print t
    }
    f = 0
  }
  !f
' content.js long.js

perl -pe '
  $repl //= do{local $/;<STDIN>;};
  next unless my $e = /BEGIN/.../END/;
  $_ = $e =~ /E0/ ? $repl.$_
     : $e == 1 ? $_
     : s/.*//sr;
' long.js < content.js

contnt=$(< "content.js" sed -e 's/^/ /')

cat - <<eof | ed -s - long.js
1m1
/BEGIN/+1,/END/-1c
$contnt
.
?BEGIN?+1,/END/-1s/^ //
wq
eof

답변2

이 유용한 답변에서 sed를 사용하는 방법을 찾았습니다.https://stackoverflow.com/a/49511949/2028440

sed -e '/ProcessCoverageController.createExampleQueries =/,/ProcessCoverageController.$inject/!b' -e '/ProcessCoverageController.$inject/!d;r content.js' -e 'd' long.js

관련 정보