あるファイルの文字列を別のファイルの内容全体に置き換えるsed(またはawk)コマンドを作成したいと思います。

あるファイルの文字列を別のファイルの内容全体に置き換えるsed(またはawk)コマンドを作成したいと思います。

あるファイルの文字列を別のファイルの内容全体に置き換えるsed(またはawk)コマンドを作成したいと思います。コンテンツをインポートする2番目のファイルには1行以上があります。

$ cat file.txt 
TEXT1 
TEST2 
TEST3 

そして

$ cat other_file.txt 
there are multiple lines1 
there are multiple lines2 
there are multiple lines3 

私は出力が次のようになります:

$ cat file3.txt
there are TEXT1 
TEST2 
TEST3 lines1

there are TEXT1 
TEST2 
TEST3 lines2

there are TEXT1 
TEST2 
TEST3 lines3

私はこれを試しました:

sed -i -e '/PLACEHOLDER/ r file' -e s/PLACEHOLDER// otherFile

しかし、それは私に正しい出力を提供しません。

「複数」キーワードをファイルの各行のすべての項目に置き換えます。これが明確になることを願っています。

答え1

m4マクロプロセッサを使用して、PLACEHOLDER他のファイルを含むマクロを定義します。

$ cat file
foo PLACEHOLDER baz
$ cat otherfile
These are the
multi-line contents
of the other file.
$ m4 -D PLACEHOLDER='include(otherfile)' file
foo These are the
multi-line contents
of the other file.
 baz

otherfileこれには、最後の改行文字を削除しないままのテキストが含まれます。

答え2

すべてのUnixシステム上のすべてのシェルでawkを使用し、要件に1つの可能な説明を提供します(スペースで区切られた「単語」で完全な単語文字列を一致させたい場合は、代替テキストに逆参照メタ文字またはその他の一般的な問題があります。ある文字を含めることができます。

$ cat tst.awk
BEGIN {
    ORS = RS RS
    old = "multiple"
}
NR==FNR {
    new = (NR>1 ? new RS : "") $0
    next
}
{
    for ( i=1; i<=NF; i++ ) {
        if ( $i == old ) {
            $i = new
        }
    }
    print
}

$ awk -f tst.awk file.txt other_file.txt
there are TEXT1
TEST2
TEST3 lines1

there are TEXT1
TEST2
TEST3 lines2

there are TEXT1
TEST2
TEST3 lines3

答え3

使用幸せ(以前のPerl_6)

~$ raku -e 'my @a = dir(test => "Matsuo_Bashō.txt").IO.lines.join("\n"); for lines[0..9] { put S/e/@a[]/ };'  alphabet.txt
a
b
c
d
No one travels
Along this way but I,
This autumn evening.
f
g
h
i
j

Original_Fileが置き換えられました==alphabet.txt

~$ raku -e 'for lines[0..9] { .put };' alphabet.txt
a
b
c
d
e
f
g
h
i
j

挿入する2番目のファイル==Matsuo_Bashō.txt

~$ raku -e 'put dir(test => "Matsuo_Bashō.txt").IO.lines.join("\n");'
No one travels
Along this way but I,
This autumn evening.

つまり、「挿入」したいファイルを取得し、Rakuのdir()ルーチンを使用してそれを読み取り、@a配列に保存します。次に、コマンドラインから2番目の「ターゲット」ファイルを読みます(ここではアルファベット順)。 「big-S」置換演算子で置き換えると、S///Rakuは結果文字列を出力します。注:上記のコードはコードの最初の項目のみを置き換えます。グローバル交換にするには(認識シーケンス内のすべての項目を交換する)、副詞をe追加します。またはより簡単には。:globalS:global///S:g///

代替にはバックスラッシュは必要ありません@a。最後にインデックス付き角かっこを追加します(中かっこも@a[]機能します。以下を参照)。

置換せずに、最初のファイルで認識されたシーケンスの後に2番目のファイルに挿入するには、反転アサーションを使用するように置換演算子を変更し、置換の前に改行を追加します。

{ put S/ <?after e> /\n@a[]/ }

#OR

{ put S/ <?after e> /\n{@a}/ }

最後に、ファイルをslurp一度に編集できることに注意してください。 Rakuを使用するルーチンはdir()次のとおりです。

  • dir(test => "Matsuo_Bashō.txt").IO.slurp;

...しかし、追加の改行文字が出力に追加されます。slurpとを使用してtrim-trailing上記の回答を複製することができます(以下のdir()ファイル名文字列を参照する簡単な方法は、これを山かっこで囲むことです)。

~$ raku -e 'my @a = dir(:test<Matsuo_Bashō.txt>).IO.slurp; for lines[0..9] { put S/e/{@a[].trim-trailing}/ };'  alphabet.txt

https://raku.org

関連情報