Belirli bir uzunluğu aşan çizgileri bulun


Yanıtlar:


89

Testlerime göre hız düşürme sırasına göre (UTF-8 yerel ayarındaki bir GNU sisteminde ve ASCII girişinde):

grep '.\{80\}' file

perl -nle 'print if length$_>79' file

awk 'length>79' file

sed -n '/.\{80\}/p' file

Hariç perl¹ biri (veya awk/ grep/ sedgibi uygulamaları ( mawkmulti-byte karakterleri desteklemeyen veya BusyBox)) sayısı bakımından uzunluğunu sayar, karakterlerin (uygun LC_CTYPEyerine yerel ayarının ayar) bayt .

Girdide geçerli karakterlerin bir kısmını oluşturmayan baytlar varsa (bu, bazen yerel ayarın karakter kümesi UTF-8 ve giriş farklı bir kodlamada olduğunda olur), o zaman çözüme ve araç uygulamasına bağlı olarak, bu baytlar 1 karakter olarak sayılacak veya 0 eşleşmeyecektir ..

Örneğin, bir UTF-8 yerel ayarında 30 asa 0x80 bayt, 30 bs, 0x81 bayt ve 30 UTF-8 és (0xc3 0xa9 olarak kodlanmış) içeren bir satır .\{80\}GNU ile eşleşmeyecek grep/ sed(bu bağımsız 0x80 bayt uyuşmuyor .), 30 + 1 + 30 + 1 + 2 * 30 = 122 uzunluğunda perlveya mawk3 * 30 = 90 uzunluğunda olur gawk.

Bayt cinsinden saymak istiyorsanız, yerel ayarı ile Cile düzeltin LC_ALL=C grep/awk/sed....

Bu, 4 çözümün hepsinin de yukarıdaki satırın 122 karakter içerdiğini düşünmesini sağlar. İçeride perlve GNU araçları dışında, NUL karakterleri içeren satırlar için (0x0 bayt) hala potansiyel sorunlarınız olacaktır.


Though perlDavranış, PERL_UNICODEçevre değişkeninden etkilense de


"Etkin" derken ne demek istiyorsun?
rowantran

Bence insan yapımı yazım etkinliği demektir. Zaten awkdüşerse ($0), daha yakın gelebilir ;
Thor,

9
BTW, regexp'i satırın başına bağlarsanız ^, biraz daha hızlı olur: örn grep '^.\{80\}' file.
cas,

4
Perl çözümü, diğer tüm çözümlerin aksine, UTF-8 gibi değişken boyut kodlamasını hesaba katmaz.
BatchyX

6
Yeterince büyük N değerleri grep ile başarısız olur ancak awk ile başarılı olur. (örneğin başarılı olurken grep '^.\{1000\}' filedöner .)grep: invalid repetition count(s)awk 'length>1000' file
mdahlman

1

Kabuk yaklaşımı:

while IFS= read -r line || [ -n "$line" ];
do 
    [ "${#line}" -gt 79 ] && printf "%s\n" "$line"
done < input.txt

Python yaklaşımı:

python -c 'import sys;f=open(sys.argv[1]);print "\n".join([ l.strip() for l in f if len(l) >79 ]);f.close()' input.txt

Veya okunabilirlik için kısa bir komut dosyası olarak:

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
    for line in f:
        if len(line) > 79:
            print line.strip()

Newline karakterini \nhesaplamalardan çıkarmak istiyorsak if len(line) > 79,if len(line.strip()) > 79

Yan not: bu Python 2.7 sözdizimidir. print()Python 3 için kullanın

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.