sed -i
シンボリックリンクで実行すると、リンクが壊れてオブジェクトファイルに置き換えられるのはなぜですか?この状況を避ける方法は?
例えば。
$ ls -l pet*
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:46 pet
lrwxrwxrwx 1 madneon madneon 6 mar 23 16:48 pet_link -> pet
$ sed -i 's/cat/dog/' pet_link
$ ls -l pet*
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:48 pet
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:49 pet_link
なぜエラーと見なされないのですか?
答え1
-i
/flag--in-place
ファイルを所定の位置に編集します。デフォルトでは、指定さsed
れたファイルを読み込み、そのファイルの処理内容を一時ファイルに出力し、元のファイルがシンボリックリンクであることを確認せずに、元のファイルの上に一時ファイルをコピーします。
GNUには必要に応じて動作させるフラグがsed
あります。--follow-symlinks
$ echo "cat" > pet
$ ln --symbolic pet pet_link
$ sed --in-place --follow-symlinks 's/cat/dog/' pet_link
$ cat pet
dog
答え2
これはバグではなく、意図的に設計されていますsed
。Sトレメ緊急室itorはファイルエディタではありません。デフォルトではコピーを作成し、元のファイルをコピーに置き換えます。バッシュFAQ
ex
あるいは、同様の代替構文を持つコマンドを代わりに使用できます。
ex +%s/cat/dog/ge -scwq pet_link
または複数のファイル:
ex "+bufdo! %s/cat/dog/ge" -scxa **/pet_link*
シンボリックリンクは壊れません。
答え3
私もこれがうまくいくことを知りました(シンボリックリンクとハードリンクを保存します):
sed 's/cat/dog/' pet_link > pet_link.tmp
cat pet_link.tmp > pet_link
rm pet_link.tmp
答え4
時々、私たちは読んだのと同じファイルに書き込むために解決策を使います。以下は、マニュアルページから抜粋した内容です。
sponge reads standard input and writes it out to the specified file.
Unlike a shell redirect, sponge soaks up all its input before opening
the output file. This allows constructing pipelines that read from and
write to the same file.
It also creates the output file atomically by renaming a temp file into
place, and preserves the permissions of the output file if it already
exists. If the output file is a special file or symlink, the data will
be written to it.
通常、inodeを保存するために使用されますが、シンボリックリンクを保存できることを示すスニペットは次のとおりです。
# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
rm -f pet pet_link
echo "cat" > pet
pl " Input data file $FILE:"
head -v pet
pl " Results, before sed:"
ln --symbolic pet pet_link
ls -ligG pet pet_link
# sed --in-place --follow-symlinks 's/cat/dog/' pet_link
pe
pe " Results, after sed:"
sed 's/cat/dog/' pet_link | sponge pet_link
head -v pet
ls -ligG pet pet_link
次を生成します。
-----
Input data file data1:
==> pet <==
cat
-----
Results, before sed:
1571283 -rw-r--r-- 1 4 Nov 26 23:03 pet
1571286 lrwxrwxrwx 1 3 Nov 26 23:03 pet_link -> pet
Results, after sed:
==> pet <==
cat
1571283 -rw-r--r-- 1 4 Nov 26 23:03 pet
1571286 lrwxrwxrwx 1 3 Nov 26 23:03 pet_link -> pet
そのようなシステムでは:
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.9 (jessie)
bash GNU bash 4.3.30
スポンジコードに包装がありますその他のユーティリティ- いくつかの詳細:
sponge soak up standard input and write to a file (man)
Path : /usr/bin/sponge
Package : moreutils
Home : http://kitenet.net/~joey/code/moreutils/
Version : 0.52
Type : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
私たちの店では、ファイルが非常に大きい場合に備えて一時ファイルに書き込むことができるバージョンを作成しました。
このパッケージはDebian、Fedora、macOS(brew経由)などで利用できます。乾杯、