Bir dosyanın yerinde modifikasyonu nasıl yapılıyor?


10

Bir dosyanın "yerinde" modifikasyonu ne şekilde sed -iveya ne perl -ianlama gelir?
Benim sorum bu yerinde yapılan değişikliğin nasıl yapıldığıyla ilgili. Kopyalanan dosya değişiklik kopyada yapılıyor ve orijinali değiştiriliyor mu? Veya orijinal dosya bir şekilde yerinde mi değiştiriliyor?


Göz at backreference.org/2011/01/29/in-place-editing-of-files bu konunun ayrıntılı bir açıklama için.
scy

Bu nedenle, exveya ile nasıl yapılır vi?
Wildcard

@Wildcard - bunların her birinin bir sistemi vardır. exbir posta dosyasını tutar ( dead.mailgenellikle sizin gibi bir şey veya posta biriktiricinize yakın bir yerde) . teknik özellikleri kontrol edin - her birinin büyük uzunluklarda tanımlanmış durumu vardır ... exçoğu durumda kendi ikili biçimine sahiptir ( -rescuedosyanıza bakın) ve bu ayrı geçici arabellek dosyalarını (muhtemelen altı kadar) önceden sıfırlamak için kullanılır . yani bu kopyaları girdi blokları düzenleme tamponlar ve senkronizasyon yazma başına değişiklik başına ofset :!written?
mikeserv

Yanıtlar:


18

sed geçici bir dosya oluşturur, çıktıyı bu dosyaya yazar ve geçici dosyayı orijinalin üstüne yeniden adlandırır.

Aşağıdakileri kullanarak neler olduğunu izleyebilirsiniz 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 +++

Bu işlem tüm dosya işlemlerini günlüğe kaydeder sed: yeni bir dosya oluşturur (güvenli bir şekilde O_CREAT|O_EXCL), verileri içine yazar ve sonra orijinal dosyamın üzerine geri taşır a.

sed -iyedekleme için kullanılacak bir sonek kabul eder ve bu durumda orijinali önce (yeniden adlandırmak yerine) yoldan çıkarır. Bu argüman BSD'lerin çoğunda zorunludur sed. Bu durumda, dizinde doğru adda hiçbir dosya olmadığında kısa bir süre olur.

perl son sürümlerde girdi dosyasını açar, ardından siler ve aynı adla yeni bir dosya oluşturur:

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

unlinkZaten açık olan bir dosyayı sildiğinizde ( ), tutamacı çevresinde tuttuğunuz sürece ona erişmeye devam edersiniz, böylece verileri silinmiş dosyadan okumaya devam edebilir. Bu şekilde perlgeçici bir dosya yerine doğrudan çıktı dosyasına yazar: ek dosya oluşturulmaz, ancak işlem sırasında dosyayı okursanız, sedyaklaşımından farklı olarak kısmi içerik alırsınız . İşlemin başlangıcında (olduğu gibi sed -i .bak) doğru adda bir dosya olmadığında da kısa bir süre vardır .


Hem sedve perlirade:

  • Sembolik bir bağlantıyı sıradan bir dosyayla değiştirin.
  • Sabit bağlantıları koparın.
  • Mümkünse grup sahipliğini koruyun.
  • Dosyayı, içinde olmadığınız setgidbir gruba aitseniz ve kök değilseniz , varsayılan grubunuzla (veya bu dizinin biti varsa üst dizinin grubuyla ) oluşturun.
  • Kökseniz dosya sahipliğini koruyun.
  • Temel izinleri koruyun.
  • Koruma setuidve setgrpbitleri halinde elde edilen grup, başlayan grup ile aynıdır.
  • Yapışkan ucu koruyun.
  • Değil xattrs korumak.

sed niyet:

  • ACL'leri koru (Linux'ta; başkalarını bilmiyorum) .

perl niyet:

  • Değil EKL'lerini korumak.

Yukarıdakiler GNU içeren Linux sedve (FreeBSD türevi) ile Mac OS X için geçerlidir sed.


3

@ Homer'ın cevabına ek olarak perldoc perlrun:

"<>" yapısı tarafından işlenen dosyaların yerinde düzenleneceğini belirtir. Bunu, giriş dosyasını yeniden adlandırarak, çıktı dosyasını orijinal adıyla açıp print () deyimleri için varsayılan olarak bu çıktı dosyasını seçerek yapar. Uzantı, sağlanmışsa, aşağıdaki kuralları izleyerek yedek kopya oluşturmak üzere eski dosyanın adını değiştirmek için kullanılır:

Herhangi bir uzantı sağlanmazsa, yedekleme yapılmaz ve geçerli dosyanın üzerine yazılır.

Uzantı bir * içermiyorsa, geçerli dosya adının sonuna sonek olarak eklenir. Uzantı bir veya daha fazla * karakter içeriyorsa, her * geçerli dosya adıyla değiştirilir.

Unutmayın, hiçbir yumuşak bağlantı veya sabit bağlantı korunmaz:

-İ, aynı adda yeni bir dosya oluşturmadan önce orijinal dosyayı yeniden adlandırdığı veya sildiğinden, UNIX stili yumuşak ve sabit bağlantıların korunmayacağını unutmayın.

Son olarak, komut satırında hiçbir dosya verilmediğinde -i anahtarı yürütmeyi engellemez. Bu durumda, yedekleme yapılmaz (orijinal dosya elbette belirlenemez) ve işlem beklendiği gibi STDIN'den STDOUT'a ilerler.

Eğer kullanmalıdır nedeni de açıklıyor -iile -pseçeneğiyle veya açık kullanmak printBirlikte düzenlemek INPLACE istiyorsanız deyimi perl:

# Opps, file will be truncated, becomes empty
$ perl -i.bak -ne 's/123/qwe/' file

# Right way
$ perl -i.bak -ne 's/123/qwe/;print' file

# Or
$ perl -i.bak -pe 's/123/qwe/' file
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.