Yanıtlar:
Ile sed
, gibi:
sed '20,37d; 45d' < input.txt > output.txt
Bunu yerinde yapmak istiyorsanız:
sed --in-place '20,37d; 45d' file.txt
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 :)
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
, ,p
ritmi rint ile değiştirin . Orijinal dosyayı sağlam tutmak ve başka bir dosyaya yazmak istiyorsanız, yeni dosya adını w
rite alt komutuna aktarabilirsiniz :
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
Her d
seç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.
q
Komut sonunda yararlı mı ? Her iki şekilde de çıkıyor sanırım.
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:
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
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?
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.
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.
Vim'i Ex modunda kullanabilirsiniz:
ex -sc '20,37d|45d|x' file
d
silmek
x
kaydet ve kapat