ファイルを内部で変更するには?

ファイルを内部で変更するには?

ファイルの「内部」修正(たとえば、または経由sed -i)とはどういうperl -i意味ですか?
私の質問は、この内部修正を実行する方法です。ファイルをコピーしてコピーを変更してからソースを置き換えますか?それとも元のファイルを適切に修正しましたか?

ベストアンサー1

sed一時ファイルを作成し、ファイルに出力を書き込み、元のファイルに基づいて一時ファイルの名前を変更します。

以下を使用して、何が起こるのかを観察できます。strace:

$ strace -e trace=file sed -i -e '' a
execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0
<...trimmed...>
open("a", O_RDONLY)                     = 3
open("./sedxvhRY8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("./sedxvhRY8", "a")              = 0
+++ exited with 0 +++

これはすべてのファイル操作を記録しますsed。新しいファイル(使いやすいO_CREAT|O_EXCL)を作成し、ここにデータを書き込み、元のファイルの先頭に戻りますa

sed -iバックアップ用のサフィックスを許可します。この場合、元のファイルを最初に移動します(一番上の名前を変更する代わりに)。このパラメータはほとんどのBSDに必須ですsed。この場合、ディレクトリに正しい名前のファイルがしばらく存在しません。

perl最新バージョンで入力ファイルを開き、削除して同じ名前の新しいファイルを作成します。

open("a", O_RDONLY)               = 3
unlink("a")                       = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4

削除すると(unlink)すでにファイルを開いている場合は、ハンドルを保持している限り、そのファイルへのアクセス権を維持するため、削除されたファイルからデータを読み続けることができます。この方法では、perl出力ファイルは一時ファイルではなく直接作成されます。追加のファイルは生成されませんが、プロセス中にファイルを読み取ると、withのsed方法とは異なり、部分的な内容が得られます。また、正しい名前のファイルを持たない短い期間がありますが、これはプロセスの終わりではなく最初にあります(図を参照sed -i .bak)。


両方sedperl両方:

  • シンボリックリンクを通常のファイルに置き換えます。
  • ハードリンクを切断します。
  • 可能であれば、グループの所有権を維持してください。
  • setgidファイルがあなたが属していないグループに属し、あなたがルートでない場合、ファイルはデフォルトグループ(またはディレクトリにそのビットがある場合は親ディレクトリのグループ)を使用して作成されます。
  • ルートの場合は、ファイルの所有権を維持してください。
  • 基本的な権限を維持してください。
  • 保存setuidしてsetgrpビット、もし結果のグループは開始されたグループと同じです。
  • 粘着性のある部分を維持してください。
  • いいえxattrsが予約されました。

sedする:

  • ACLを保存します(Linuxの場合、他の場合はわかりません)

perlする:

  • いいえACLを維持してください。

上記は、GNUを使用するLinuxsedとFreeBSD派生製品を使用するMac OS Xの両方に適用されますsed

おすすめ記事