Sed -i'nin sembolik bağlantıları yok etmesini nasıl önleyebilirim?


21

sed -iSymlink'te yürütülen neden bu bağlantıyı yok eder ve hedef dosyayla değiştirir? Bundan nasıl kaçınılır?

Örneğin.

$ 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

Ve neden bir hata olarak görülmüyor?

Yanıtlar:


25

-i/ --in-placeBayrak yerde bir dosyayı düzenler. Varsayılan olarak, sedverilen dosyayı okur, çıktısını geçici bir dosyaya işler, ardından orijinalin bir sembolik olup olmadığını kontrol etmeden geçici dosyayı orijinalin üzerine kopyalar.

GNU'nun istediğiniz gibi davranmasını sağlayan sedbir --follow-symlinksbayrağı vardır :

$ echo "cat" > pet
$ ln --symbolic pet pet_link
$ sed --in-place --follow-symlinks 's/cat/dog/' pet_link
$ cat pet
dog

6
Bir dosyayı yerinde düzenlemez, ancak geçerli dizindeki dosyanın geçici bir kopyasını düzenler ve ardından bu geçici kopyayı orijinalin üzerine taşır.
mikeserv

@mikeserv Soru arayüzle ilgili olduğu için uygulama ayrıntılarını atladım. Gerçi bilmek güzel, teşekkürler!
Anko

1

Bu bir hata değil, bu bir tasarım editörü çünkü bir dosya editörü değil sed, bir S tream ED itor . Temel olarak bir kopya oluşturur ve orijinal dosyayı kopyayla değiştirir. BashFAQ

Alternatif exolarak, ikame için benzer sözdizimine sahip komutu kullanabilirsiniz , örn.

ex +%s/cat/dog/ge -scwq pet_link

veya birden fazla dosya:

ex "+bufdo! %s/cat/dog/ge" -scxa **/pet_link*

Sembolik bağlantıları yok etmez.

İlgili: sed'in hardinksleri yok etmesini nasıl önleyebilirim?


0

Bunun da iyi çalıştığını görüyorum (hem sembolik hem de sabit bağlantıları koruyarak):

sed 's/cat/dog/' pet_link > pet_link.tmp
cat pet_link.tmp > pet_link
rm pet_link.tmp

0

Okunduğu zaman aynı dosyaya yazmak için kullandığımız bir çözüm var. İşte man sayfasından bir alıntı:

   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.

Genelde inode'ları korumak için kullandığım halde sembolik bağlantıları koruyabildiğini gösteren bir snippet:

# 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

hangi üretir:

-----
 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

Gibi bir sistemde:

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30

Sünger kodu moreutils paketinde mevcuttur - bazı ayrıntılar:

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 ...)

Mağazamızda, çok büyük dosyalar için geçici bir dosyaya yazan bir sürüm yazdık.

Paket Debian, Fedora, macOS (demlemek yoluyla), vb.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.