File1
コンテンツ:
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
File2
コンテンツ:
line1-file2 "25"
line2-file2 "24"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
Perl/shell スクリプトが実行された後、File2
内容は次のようになります。
line1-file2 "25"
line2-file2 "24"
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
File1
つまり、File2
「Pointer」を含む行の前にinの内容を貼り付けます。
答え1
このsed
ユーティリティには修正操作を実行する機能があります。
sed -i -e '/Pointer/r file1' file2
しかし、これはあなたを針コンテンツの上の行ですfile1
。簡単に言えば、遅延ライン出力です。
sed -n -i -e '/Pointer/r file1' -e 1x -e '2,${x;p}' -e '${x;p}' file2
GNUの使用sed
:
sed '/Pointer/e cat file1' file2
~によると手動のためe [command]
:
rコマンドとは異なり、このコマンドの出力はすぐに印刷されます。 r コマンドは、現在の期間が終了するまで出力を遅延します。
答え2
sed
またはを使用しないでくださいawk
。
まず、パターンのある行を見つけます。
line=$(grep -n 'Pointer' file2 | cut -d ":" -f 1)
次に、3つのコマンドを使用して目的の結果を出力します。
{ head -n $(($line-1)) file2; cat file1; tail -n +$line file2; } > new_file
これは3回訪問する必要があるという欠点がありますが、解決策file2
よりもきれいになります。sed
awk
答え3
awk
これをかなり簡単にします。
ファイルの前に次の行を挿入します。
awk '/Pointer/{while(getline line<"innerfile"){print line}} //' outerfile >tmp
mv tmp outerfile
その行の後に内部ファイルを印刷するにはPointer
モード順序を切り替え(デフォルトの動作を得るにはセミコロンを追加する必要があります)、変数を削除できますline
。
awk '//; /Pointer/{while(getline<"innerfile"){print}}' outerfile >tmp
mv tmp outerfile
まだ誰も使用していないのでperl
、
# insert file before line
perl -e 'while(<>){if($_=~/Pointer/){system("cat innerfile")};print}' outerfile
# after line
perl -e 'while(<>){print;if($_=~/Pointer/){system("cat innerfile")}}' outerfile
答え4
簡単な作業ed
:
ed -s file1 <<IN
/Pointer/-r file2
,p
q
IN
-r file1
指定されたファイルを指定された行に読み取った後、この場合、最初の行より前の行が一致しますPointer
。したがって、複数行に表示されてもfile2
コンテンツは一度だけ挿入されます。Pointer
一致する各行の前に挿入するには、g
グローバルフラグを追加します。
ed -s file1 <<IN
g/Pointer/-r file2
,p
q
IN
ファイルをその場所で編集するには、,p
に置き換えます。w
許可されたsed
回答はほとんどの場合機能しますが、マーカーが最後の行にある場合、コマンドは期待どおりに機能しません。つまり、File1
マーカーの後にコンテンツが挿入されます。
私は最初に次のことを試しました。
sed '/Pointer/{r file1
N}' file2
また、うまく機能しますが(ループr
の最後で魔法が機能するように)、マーカーがN
最後の行にある場合(最後の行の後に分岐がない場合)、同じ問題が発生します。この問題を解決するには、入力に改行文字を追加するだけです。
sed '/Pointer/{ # like the first one, but this time even if the
r file1 # marker is on the last line in File2 it
N # will be on the second to last line in
} # the combined input so N will always work;
${ # on the last line of input: if the line is
/^$/!{ # not empty, it means the marker was on the last
s/\n$// # line in File2 so the final empty line in the
} # input was pulled i\n: remove the latter;
//d # if the line is empty, delete it
}' file2 <(printf %s\\n)
file2
一致する各行の前に内容が挿入されます。一致する最初の行の前にのみ挿入するには、oopを使用してファイルの終わりに達するまで次の行をl
引きます。n
sed '/Pointer/{
r file2
N
:l
$!n
$!bl
}
${
/^$/!{
s/\n$//
}
//d
}' file1 <(printf %s\\n)
これらのsed
ソリューションを使用すると、所定の場所で編集する機能が失われます(ただし、別のファイルにリダイレクトすることはできます)。