Sed '1! G; h; $! D' komutu bir dosyanın içeriğini nasıl tersine çevirir?


20

Benim sorum ters cevap bu soru için bu cevapsed verilen -özel çözüm ile ilgilidir . / Ben Deşifre alamıyorum o çözüm birini takip ediyor:sedgrep

sed '1!G;h;$!d' file

Birisi lütfen bu komutu deşifre edebilir mi?

VI (M) bilgisinden G'nin dosyanın son satırını gösterdiğini ve sed'de bir patlama (!) İzledikten sonra bu adresle grep -veşleşmeyeceğini söylemek gibi bir adres çalışması olduğunu biliyorum. Ama bir bütün olarak, yukarıdaki satır içi sed senaryosu beni aşıyor.


3
... çok yavaş ...
mikeserv

1
Mikeserv ipuçları olarak. Bu zor sedtarifin bir dosyadaki satırları tersine çevirmek için son derece verimsiz bir yol (O (n ^ 2/2) karmaşıklığı) olduğuna dikkat edilmelidir . Çok sayıda satırı olan dosyalar için engelleyici derecede yavaş olacaktır. Çok daha verimli bir hat sırası ters çevirme alternatifi için tacGNU coreutils'e bakınız .
arielf

Yanıtlar:


35

Bu, dosyayı satır satır tersine çevirir.

sed '1! G; h; $! d' dosyası

İlk olarak, sedbir tutma alanı ve bir desen alanı vardır . Bu özel komuta konsantre olmadan önce aralarında ayrım yapmak zorundayız.

Ne zaman sedyeni bir satır okur, bu model uzaya yüklenir. Bu nedenle, her yeni satır işlendiğinde bu alanın üzerine yazılır. Öte yandan, tutma alanı tüm işleme boyunca tutarlıdır ve değerler daha sonra kullanılmak üzere orada saklanabilir.


Komuta:

Orada bu açıklamada 3 komutlar şunlardır: 1!G, hve$!d

  • 1!Gbu araçlar G, komut ilk hariç tüm hat üzerinde yürütülür ( !ortadan 1). tutma boşluğundaki şeyi desen boşluğuna eklemekG anlamına gelir .

  • hher satır için geçerlidir. Bu kopyalar desen tutma boşluğuna uzay (ve üzerine yazar bunu).

  • $!dson satır hariç her satır için geçerlidir ( $son satırı temsil eder, !reddeder). dsatırı silme komutudur (desen alanı).


  1. Şimdi, ilk satır okunduğunda, komutu sedyürütür h. İlk satır tutma alanına kopyalanır. Ardından, $!koşulla eşleştiği için silinir . sedikinci satırla devam eder.
  2. İkinci satır koşulla eşleşir 1!(bu ilk satır değildir) ve dolayısıyla (ilk satıra sahip olan) tutma alanı (ikinci satıra sahip olan) desen alanına eklenir. Bundan sonra, desen uzayında, şimdi bir satırsonu ile sınırlanan ikinci satır ve ardından ilk satır vardır. Şimdi, hkomut uygulanır (her satırda olduğu gibi); desen alanındaki her şey tutma alanına kopyalanır. Üçüncü ifade ( $!d) uygulanır: Çizgi, desen alanından silinir.
  3. Adım 2 şimdi tüm satırlarla yapılır. Son satıra geçiyoruz.
  4. Son satırda ( $), 2. Adımın neredeyse tamamı yapılır, ancak silme parçası ( d) yapılmaz . sed, olmadan çağrıldığında -n, her girdi satırı için işlemin sonunda desen alanını otomatik olarak yazdırır. Böylece, silinmediğinde, desen alanı yazdırılır. Artık tüm satırları ters sırada içermektedir .

1
@Meek No, hkomut desen alanını bitene kadar devam eden tutma alanına kopyalar sed. Betiğin sona ermesinden sonra her şey temizlenir, çünkü ikili çıkılır.
kaos

2
Bekleme alanını vim kayıtları gibi düşünebilir miyiz? Onlar da numaralandırılmış mı? Yoksa bunlardan sadece biri var mı?
Geek

2
@Geek Burada sedsadece bir tane bekletme alanı var. Bir şey içerebilen bir değişken gibidir.
kaos

1
@ user1717828 İlk satır yazdırılmasaydı, işlendiğinde. Sed ile çağrılmadığından -nson satır hariç her satırı silmeliyiz. Son satırda sed, tutma alanından desen alanına kadar her şeyi ekler. Çünkü dkomut yürütülmez, çizgi (bu hat şimdi tersine tüm dosyayı içerir) basılır.
kaos

1
(1) OP'nin alt sorusu / gözlemi (yorumda), “bu yüzden son satırdakih komut bir nevi op-olmayan türdür.” (Vurgu eklenmiş ve biraz başka kelimelerle yazılmış). O haklı; ne zaman işleniyor son girişin hattı , (desen uzay bunu eklemek için sırayla) yer tutmaya okur, sonra da kopya tutma alanı, desen uzay tekrar asla başvurulmaz . Biz de söyleyebiliriz ya da . (2) diyerek kullanmaktan kaçınabiliriz . sedGhsed 'G;$!h;$!d'sed 'G;$!{h;d}'dsed -n 'G;h;$p'
Scott
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.