web-dev-qa-db-ja.com

SED:ファイルから別のファイルの特定の行に行をコピーします

次の例を使用してこれを行うことができます。最初のコマンドはfile1からpatchまでの16 ... 80行を出力しますが、2番目のコマンドはpatchの内容を行18の後にfile2に挿入します。

sed -n 16,80p file1>patch
sed -i 18rpatch file2

ただし、一時ファイルを中間で使用せずに、sedを使用する1つのコマンド(awkなどではない)で、あるファイルから別のファイルに直接コピーしたいと思います。私はこれが可能であると確信していますが、方法がわかりません。

8
mYself

Sedでこれを行うには、追加のシェルトリックが必要です。 bashを想定すると、

_sed -i 18r<(sed '16,80!d' file1) file2
_

ここで、<(sed '16,80!d' file1)は、_sed '16,80!d' file1_の出力を読み取ることができるパイプの名前に置き換えられます。

一般的に、awkは複数の入力ファイルを処理できるように装備されているため、awkを使用すると(少し長い場合)これを行う方が良いと思います。例えば:

_awk 'NR == FNR { if(FNR >= 16 && FNR <= 80) { patch = patch $0 ORS }; next } FNR == 18 { $0 = patch $0 } 1' file1 file2
_

これは次のように機能します。

_NR == FNR {                       # While processing the first file
  if(FNR >= 16 && FNR <= 80) {    # remember the patch lines
    patch = patch $0 ORS
  }
  next                            # and do nothing else
}
FNR == 18 {                       # after that, while processing the first file:
  $0 = patch $0                   # prepend the patch to line 18
}
1                                 # and print regardless of whether the current
                                  # line was patched.
_

ただし、このアプローチは、ファイルのインプレース編集には適していません。これは通常問題ではありません。私は単に使います

_cp file2 file2~
awk ... file1 file2~ > file2
_

洋ナシの形になった場合に備えてバックアップをとるという追加の利点がありますが、結局それはあなた次第です。

5
Wintermute

私は使用して同様のことをしました:

    head -80 file | tail -16 > patch

ローカルバージョンのheadおよびtailのドキュメントを確認し、要件に合わせて2つの整数を変更してください。

3
Arif Burhan

私はこの問題を抱えていました、たとえば、20行のテキストファイル(test.txt)で2つのステップ(1-tail 2-head)でそれを行いました。13行から17行を別のファイル(最終。 txt)、

tail -8 test.txt> temp.txt
ヘッド-5 temp.txt> final.txt

0
Farshad Falaki
_sed -i '1,15 d
        34 r patch
        81,$ d' YourFile

# oneliner version
sed -i -e '1,15 d' -e '34 r patch' -e '81,$ d' YourFile
_
  • 行の順序は重要ではありません。
  • あなたは少し適応するか、このような変数でそれをバッチ処理できます

sed -i "1,16 d $(( 16 + 18 )) r patch 81,$ d" YourFile

ただし、この場合は行数に関するセキュリティを追加します。

  • r行が1行を超える場合でも、次の行は元の場所から数えられ、最終的なファイルは80-16行を超えます

取られた行、除外された行、または変更された行(34はトリミングされたファイルの18行目など)を正確にテストしませんが、プリンシペは同じです

このサンプルで使用されているLinesインデックス参照の説明:

  • _1,15_は削除する見出し行であるため、この場合はファイルの16行目から行を削除します
  • _34_はコンテンツを変更する行であり、最初の新しいコンテンツ(この場合は行16)の後の18行目の結果なので、16 + 18 = 34です。
  • _81,$_は削除する後続の行であり、_$_は最後の行を意味し、81は不要な後続行の最初の行(80が取られた後)です。
0
NeronLeVelu