他のファイルのパターンを一致させた後にインラインファイルのテキストを挿入する

他のファイルのパターンを一致させた後にインラインファイルのテキストを挿入する

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を削除しますFirstcat\n

出力:

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

これでファイルの内容全体を合わせるには〜サイ上記のコマンドを使用して行間の末尾の改行文字を削除するため、行の2つの部分は少し異なる動作をする必要があります。終わり行の位置とファイルの先頭を一致させます。ただし、次のようにすることもできます。

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

関連情報