sedを使用してファイルの内容を取得し、一致するパターンの後に別のファイルに挿入しようとしています。私の問題は次のようによく似ています。この問題しかし、ファイルの内容を新しい行ではなくインラインで挿入したいと思います。どうすればいいですか?
私が引用した質問の例を使用すると、最初の答えは私が望むものを正確に実行しますが、挿入がインラインで発生したいと思います。
sed '/First/r file1.txt' infile.txt
挿入する実際のデータはJSONファイルです。
[
{
"foo": "bar",
"baz": "biff",
"data": [
{
"a": 1945619,
"b": [
{
"c": 512665,
"d": "futz"
}
]
}
]
}
]
答え1
あなたがリンクした質問にはすでに良い答えがあります。改行なしで挿入する代わりに、awk
以下を使用して少し修正してください。printf
print
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
に置き換えます)。pattern
file content
perl -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/' file.txt
-i
PAT(パターン)が発生するたびに内部編集を追加します。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が挿入されるためです。cut
paste
sed
\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
これでファイルの内容全体を合わせるには〜サイ上記のコマンドを使用して行間の末尾の改行文字を削除するため、行の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文字の後の新しいパターンスペースに追加して並べ替えます。線分離記号。h
e
cat
G
\n
\n
私はecho .
すべての末尾の\n
Ewline文字を保持しましたfile
。しかし、それがあなたの風ではない場合(とにかくあなたの例とは関係ありません)それなしで行うことができ、下の交換から.
前の最初のものを削除できます。.\n
s///
パターン空間が再配置される前の様子は次のとおりです。
^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