다른 파일의 패턴을 일치시킨 후 인라인 파일의 텍스트 삽입

다른 파일의 패턴을 일치시킨 후 인라인 파일의 텍스트 삽입

sed를 사용하여 파일 내용을 가져와 일치하는 패턴 뒤에 다른 파일에 삽입하려고 합니다. 내 문제는 다음과 매우 유사합니다.이 문제, 하지만 파일 내용을 새 줄이 아닌 인라인으로 삽입하고 싶습니다. 어떻게 해야 하나요?

내가 인용한 예제 질문을 사용하면 첫 번째 대답은 내가 원하는 것을 정확히 수행하지만 삽입이 인라인으로 발생하기를 원합니다.

sed '/First/r file1.txt' infile.txt 

삽입하려는 실제 데이터는 JSON 파일입니다.

[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
]

답변1

당신이 링크한 질문에는 이미 좋은 대답이 있습니다 . 개행 없이 삽입하는 대신 awk다음을 사용하여 약간 수정하십시오 .printfprint

awk '/First/ { printf $0; getline < "File1.txt" }1' infile.txt

결과:

Some Text here
FirstThis is text to be inserted into the File.
Second
Some Text here

"첫 번째" 뒤에 공백이나 기타 구분 기호를 추가해야 할 수도 있습니다.printf $0 " "; ...


삽입된 파일에 여러 줄이 있는 경우 다음을 수행합니다.

awk '/First/{printf $0; while(getline line<"File1.txt"){print line};next}1' infile.txt

결과:

Some Text here
First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
]
Second
Some Text here

답변2

다음을 사용할 수 있습니다 perl(파일 내용을 가져와 + pattern로 바꾸기 ).patternfile content

perl -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/' file.txt

-iPAT(패턴)가 발생할 때마다 내부 편집을 추가합니다 . g예:

perl -i -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/g' file.txt

또 다른 방법은 다음을 사용하십시오 ed.

printf '%s\n' /PAT/s/PAT/\&\\ \/ - kb ". r insert.txt" j \'b j ,p q | ed -s file.txt

그 자리에서 편집하려면 다음 ,p으로 바꾸세요 w.

 printf '%s\n' /PAT/s/PAT/\&\\ \/ - kb ". r insert.txt" j \'b j w q | ed -s file.txt

아마도 아무도 이것이 어떻게 작동하는지 관심이 없을 것입니다. 그러나 어쨌든 printf명령 목록을 다음으로 전달하십시오 ed.

/PAT/s/PAT/&\             #   set address to first line matching PAT and
/                         #   split the line right after PAT
-                         #   set address one line before (return to the line matching PAT)
kb                        #   mark the current line
. r insert.txt            #   insert content of insert.txt after this line         
j                         #   join current line and the next
'b                        #   set  address to marked line (return to the line matching PAT)
j                         #   join current line and the next one
,p                        #   print file content
q                         #   quit editor

또는 printf및를 사용하지 않고 다음을 수행합니다 |.

ed -s file.txt <<< $'/PAT/s/PAT/&\\\n/\n-\nkb\n. r insert.txt\nj\n\'b\nj\nw\nq\n'

답변3

따라서 이 작업을 이식 가능하게 만드는 것은 약간 까다롭습니다 . 해당 컨텍스트에서 스크립트를 생성하려면 정규 표현식 전구체를 찾 거나 사용해야 sed합니다 . 이는 항상 ewline이 삽입 되기 때문입니다.cutpastesed\n앞으로ead의 출력 r. 그래도 GNU를 사용하면 다음과 같습니다 sed.

sed '/First/{x;s/.*/cat file/e;H;x;s/\n//}' <<\IN 
First
Second
Third
IN

e이 작업은 귀하의 주소가 나타날 때마다 수행됩니다 . 이 작업은 기존 공간에서 수행됩니다.cat/First/h(어쨌든 - 백업 버퍼 - 변경한 이후 실제로 는 이전 공간이었던 패턴 공간 x에서 발생했습니다 .)h행이 일치하는 것을 유지하려면 출력을 행에 추가하고 중간에 있는 ewline을 제거 First하십시오 .cat\n

산출:

First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
]
Second
Third

이제 파일의 전체 내용을 맞추려면~ 사이위의 명령을 사용하여 줄 사이의 후행 개행 문자를 제거하기 때문에 줄의 두 부분은 약간 다르게 작동해야 합니다.줄의 위치와 파일의 시작 부분을 일치시킵니다. 그러나 다음과 같이 할 수도 있습니다.

sed '/First/{s//&\n/;h
         s/.*/{ cat file; echo .; }/e;G
         s/\(.*\).\n\(.*\)\n/\2\1/
}' <<\IN
Third
Second
First Second Third
Third
Second
First Second Third
IN

이것은 match에서 ewline 문자로 행을 분할 하고 이를 이전 공간 \n에 저장하고 xecutes (패턴 공간을 해당 출력으로 대체)는 예약된 공간의 내용을 다른 ewline 문자 뒤의 새 패턴 공간에 추가한 다음 재정렬합니다 . 선 분리 기호.hecatG\n\n

나는 echo .모든 후행 \nEwline 문자를 유지했습니다 file. 하지만 그것이 당신의 바람이 아닐 경우(어쨌든 귀하의 예와는 관련이 없습니다)그것 없이도 할 수 있으며 아래 교체에서 .앞에 있는 첫 번째 것을 제거할 수 있습니다..\ns///

패턴 공간이 재배열되기 전의 모습은 다음과 같습니다.

^cat's output - any number of newlines.*.\nmatch on First\nrest of match$

산출:

Third
Second
First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
] Second Third 
Third
Second
First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
] Second Third

관련 정보