file1 の M 行を file2 の N 行に置き換えます。

file1 の M 行を file2 の N 行に置き換えます。

Let M=3and 。ライン入力をライン入力に変更しN=4たいです。以下を使用して文字列を置き換えることができます。Mfile1Nfile2sed

sed -i '3s/.*/stringToReplace/' file1

私はこれを使ってawk行を得ることができますNfile2

awk 'NR==4' "file2"

これら2つをどのように組み合わせることができますか?試してみると

sed -i '3s/.*/{awk 'NR==4' "file2"}/' file1

次に、Mlineを文字通りの意味に置き換えます{awk 'NR==4' "file2"}

ベストアンサー1

任意の入力を処理するためにこれを正しく実行する方法はいくつかあります。
GNUsedと以下をサポートするシステムを使用してください/dev/stdin

sed -n "${n}{p;q;}" file2 | sed -e "$m{r/dev/stdin" -e 'd;p;}' file1

または少し短い1

sed $n'!d;q' file2 | sed -e $m'{r /dev/stdin' -e 'd;p;}' file1

sedプロセスの交換をサポートするシェルを使用してください。

sed '1h;1d;'$((m+1))'x' <(sed ${n}'!d;q' file2) file1

次のように書くこともできます。

sed ${n}'!d;q' file2 | sed '1h;1d;'$((m+1))'x' - file1

デフォルトでは、1回のsed呼び出しは行を抽出し、別の呼び出しnからfile2最初のオペランドに読み込みますsed。これを保持バッファに保存して削除し、2番目のオペランドの内容を読み込みます。つまりfile1、交換時にラインでバッファm+1(入力結合))。

sed以下を介してスクリプトファイルの読み取りをサポートしている人:-fstdin

sed ${n}'!d;i\
'${m}'c\\
s/\\/&&/g
q' file2 | sed -f - file1

ここで最初のsedものは、行を次のスクリプトファイルnに置き換えます。file2

${m}c\
line_n_content_here_with_any_backslash_escaped

次に、2番目の項目のsed処理に使用されますfile1(例:その行をm次のテキストに置き換えます。)。 anyを使用しa\たりテキストを追加したりするときなど、元のテキスト内のすべてのバックスラッシュ(含まれている改行も含みますが、ここには1つのみ)をエスケープする必要がありますi\c\

<backslash> characters in text shall be removed, and the following character shall be treated literally.

いずれにせよ、sed常に人気のあるs代替コマンドを使用できます。sed挿入された代替文字列がすべての予約文字をエスケープしていることを確認してください。- この特別な場合には1行です。

line=$(sed ${m}'!d;s|[\/&]|\\&|g;q' file2)

次に、次のものを交換します。

sed ${m}'s/.*/'"$line"'/' file1

大規模な入力ファイルの場合は、以下を実行できます。

{ head -n $((m-1)); { head -n $((n-1)) >/dev/null; head -n 1; } <file2; head -n 1 >/dev/null; cat; } <file1

これは次のことを行います。

print (m-1) lines from file1
discard (n-1) lines from file2
print n-th line from file2
discard m-th line from file1
print the remaining lines from file1

何人かのhead人々は愚かで何をすべきかわからないが標準準拠したがって、これがすべての設定で機能するわけではありませんが、それが機能している場合はsed速度の面で優れています。awk


1:一部のシェルでは、これが機能するために履歴拡張を無効にする必要があるかもしれません!...
また、正の整数でなければならないので、ここで引用する必要はありません$n$m

おすすめ記事