Bir metin dosyasını satır uzunluğuna göre filtrelemek için Linux kabuk komutu


19

Ben dd if=/dev/sda1 of=diskimagebazı metin dosyalarını kurtarmak için gereken bir borked bölüm (düşünmek ) 30GB disk görüntüsü var . Veri oyma araçları foremostsadece iyi tanımlanmış başlıklara sahip dosyalarda çalışır, yani düz metin dosyaları değil, bu yüzden iyi arkadaşımın üzerine düştüm strings.

strings diskimage > diskstrings.txt aslında istediğim metinle karıştırılmış, çoğunlukla yararsız şeyler bir dizi dizeleri içeren bir 3GB metin dosyası üretti.

Kabaların çoğu gerçekten uzun, kırılmamış anlamsız dizeler olma eğilimindedir. İlgilendiğim şeylerin 16 kb'den az olması garanti ediliyor, bu yüzden dosyayı satır uzunluğuna göre filtreleyeceğim. İşte bunu yapmak için kullandığım Python betiği:

infile  = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
    if len(line) < 16384:
        outfile.write(line)
infile.close()
outfile.close()

Ama ileride yararlanmak üzere bu işler: Herhangi büyülü tek satırlık büyüler (düşünmek var mıdır awk, sedhat uzunluğuna göre bir dosya filtre olurdu)?

Yanıtlar:


28
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt

kendi örneğinizde olduğu gibi 16 kilobayttan daha kısa satırlar basar.

Veya Perl'den hoşlanıyorsanız:

perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt

Bu utanç verici derecede basitti. Teşekkür ederim. :)
Li-aung Yip

Ayrıca Perl sürümü eklendi :-)
Janne Pikkarainen

Awk betiği awk 'length($0) < 16384' file > output, varsayılan eylem satırı yazdırmak olduğu için yazılabilir .
glenn jackman

8

Bu Ansgar'ın cevabına benzer, ancak testlerimde biraz daha hızlı:

awk 'length($0) < 16384' infile >outfile

Diğer awk cevapları ile aynı hızda. printGerçek bir ifadenin örtük olmasına dayanır , ancak Ansgar'ın yaptığı gibi çizgiyi ayırmak için zaman ayırmaya gerek yoktur.

AWK'nin size bir ifücretsiz verdiğini unutmayın . Yukarıdaki komut şuna eşdeğerdir:

awk 'length($0) < 16384 {print}' infile >outfile

ifDiğer cevapların bazılarında olduğu gibi açık (veya etrafındaki kıvırcık küme parantezleri) yoktur.

İşte bunu yapmanın bir yolu sed:

sed '/.\{16384\}/d' infile >outfile

veya:

sed -r '/.{16384}/d' infile >outfile

16384 (veya daha fazla) karakter içeren herhangi bir satırı siler.

Tamlık için sed, eşik değerinizden daha uzun satırları kaydetmek için şu şekilde kullanabilirsiniz :

sed '/^.\{0,16383\}$/d' infile >outfile

2

Şunları yapabilirsiniz awk:

$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file

Bu, 16K karakterden (16 * 1024) daha kısa satırlar yazdırır.

grepAyrıca şunları kullanabilirsiniz :

$ grep ".\{,16384\}" /path/to/text/file

Bu, satırları en fazla 16K karakter basacaktır.


Emin olmak grepiyi bir fikir değil - emin olmak için basit bir normal ifade, ancak daha hesaplamalı olarak daha pahalı awk. "Problemi olan bir adam" Düzenli ifadeler kullanacağım! "Diyor. Şimdi iki problemi var." ;)
Li-aung Yip

Bunu yapmanın başka bir yoludur. Gönderdiğim ilk seçenek kullanıyordum awk.
Khaled

1
Normal ifade için +1, çünkü daha iyi golf oynuyor ve beni awk
manpages okumamı sağlamaz

2

Zaten verilen cevaplardan gerçekten farklı değil, ama yine de daha kısa:

awk -F '' 'NF < 16384' infile >outfile
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.