Bir dosyadaki belirli satırları (satır numaralarını kullanarak) nasıl kaldırırım?


27

Bir dosyadan kaldırmak istediğim belirli çizgiler var. Diyelim ki satır 20-37 ve sonra satır 45. Bunu satırların içeriğini belirtmeden nasıl yaparım?


Dosyan ne kadar büyük? Belleğe yüklenebilir mi?
Faheem Mitha

Birkaç kilobayt.
tshepang

Yanıtlar:


29

Ile sed, gibi:

sed '20,37d; 45d' < input.txt > output.txt

Bunu yerinde yapmak istiyorsanız:

sed --in-place '20,37d; 45d' file.txt

Yerinde yapmanın bir yolu var mı?
tshepang

Ben sed -i dosyası
önerim

1

3
Sık sık yanıltıcı terim yerinde , 'sed' ifadesinden bahsettim, bu yüzden 'man sed' ifadesine baktım: --in-place [= SUFFIX]This option specifies that files are to be edited in-place. GNU sed 'geçici bir dosya oluşturarak bunu yaptı ve çıktıyı standart çıktı yerine bu dosyaya gönderiyoruz.` ... Başka bir 'sed' hakkında bir şey bilmiyorum ama bir dere editörü ile "yerinde" güncelleme lojistiği "hesaplama" yapmıyor :)
Peter.O

2
"Yerinde" yöntemlerinin çoğu benim deneyimime göre geçici bir dosya kullanıyor.
Faheem Mitha

5

Dosya belleğe rahatça sığarsa, kullanabilirsiniz ed.
Komutlar, dikkate değer bir farkla,sed yukarıdakiyle oldukça benzer : azalan sırayla silinecek satır numaralarının / aralıklarının listesini geçmek zorundasınız (en yüksek satır / aralıktan en düşük satıra kadar). Bunun nedeni, / insert / split / join satırlarını silerken , her alt komuttan sonra metin arabelleğinin güncellenmesidir; bu nedenle, bazı satırları silerseniz, aşağıdaki satırların geri kalanı artık arabellek içinde aynı konumda olmayacaktır. sonraki alt komut yürütülür. Yani geriye doğru başlamalısın 1 . Yerinde düzenleme:ed

ed -s in_file <<IN
45d
20,37d
w
q
IN

veya

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

veya

printf '%s\n' 45d 20,37d w q | ed -s in_file

Elde edilen çıktıyı dosyaya yazmak yerine yazdırmak istiyorsanız w, ,pritmi rint ile değiştirin . Orijinal dosyayı sağlam tutmak ve başka bir dosyaya yazmak istiyorsanız, yeni dosya adını write alt komutuna aktarabilirsiniz :

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1 Her dseçenekten sonra yeni satır numaralarını hesaplamak istemediğiniz sürece , bu özel durum için oldukça önemsizdir (20-37 satırlarını sildikten sonra, yani 18 satır, satır 45 satır 27 olur), böylece koşabilirsiniz:

ed -s in_file <<IN
20,37d
27d
w
q
IN

Bununla birlikte, birden fazla satır numarası / aralığı silmek zorunda kalırsanız, geriye doğru çalışmak hiç akıllıca olmaz.


qKomut sonunda yararlı mı ? Her iki şekilde de çıkıyor sanırım.
Tom Fenech

@TomFenech - tüm uygulamalar bir şekilde çıkmaz (çoğu olsa da ... artık bunun tartışıldığı ipliği bulamıyorum ...)
don_crissti

1

Sadece hafızaya oku, değiştirin, sonra tekrar yazın. Gibi bir şey yapabilirsin

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

5 satırlık bir dosyayla test edilmiştir. Http://pleac.sourceforge.net/pleac_python/fileaccess.html sayfasındaki krediler için "Geçici Dosya Olmadan Yerinde Bir Dosyayı Değiştirme" bölümüne bakın. Ayrıca bkz. Https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python

Bazı notlar:

  1. Biri önce dosyayı kesebilir, sonra yazmak yerine yazabilir, sonra yukarıdaki gibi kesebilir. Ancak, birinin okumasını sağlayan ve sonra kesilmiş bir yazı yapabilen bir Python bayrağını tanımıyorum. Ama belki de bir şeyleri özlüyorum, çünkü belge o kadar net değil. Bu beni getiriyor

  2. Bazen Python docs gerçekten emmek. Http://docs.python.org/library/functions.html#open adresine bakınız.

    'R +', 'w +' ve 'a +' modları güncelleme için dosyayı açar ('w +' dosyasının dosyayı kısalttığına dikkat edin).

    Bu sana bir şey ifade ediyor mu? "Güncelleme için açık" nedir?

  3. Bunu python'da, stream editörü gibi tek kelimeli bir şeyin aksine daha iyi yapıp yapmadığınızı bilmiyorum. Daha taşınabilir olabilir, ancak sed'in ne kadar taşınabilir olduğunu bilmiyorum. Öyle yazdım çünkü düşük seviyeli programlamada klasik unix araçlarını kullanmaktan daha rahatım, tam olarak istediğiniz şeyi yaparlarsa iyi, ama (sanırım) genellikle daha az esnek.

  4. Bu yaklaşım (bellekteki dosyayı değiştirmek) disk alanı için belleği değiştirir. Birkaç yüz Mb'a kadar olan dosyalar için birkaç Gb belleğe sahip makinelerde Tamam çalışması gerekir. Python, dizeleri çok verimli bir şekilde işlemez, bu nedenle örneğin C / C ++ 'a geçmek performansı biraz arttırır ve bellek kullanımını büyük ölçüde azaltır.


0

Vim'i Ex modunda kullanabilirsiniz:

ex -sc '20,37d|45d|x' file
  1. d silmek

  2. x kaydet ve kapat

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.