特定の長さを超える行を見つける


回答:


90

私のテストによると、速度が低下する順に(UTF-8ロケールのGNUシステム上およびASCII入力上):

grep '.\{80\}' file

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

awk 'length>79' file

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

以外のperl(又はため¹1 awk/ grep/ sed実装(のようなmawk数で長さをカウントするマルチバイト文字をサポートしていないか、busyboxの))、文字(によるとLC_CTYPEロケールの設定)の代わりにバイト

有効な文字の一部を形成しないバイトが入力にある場合(ロケールの文字セットがUTF-8で、入力が異なるエンコーディングにある場合に発生することがあります)、ソリューションとツールの実装に応じて、それらのバイトは1文字としてカウントされるか、0または一致しません.

たとえば、UTF-8ロケールで30 asa 0x80バイト、30 b秒、0x81バイト、および30 UTF-8 é(0xc3 0xa9としてエンコード)で構成される行は、.\{80\}GNU grep/ sed(そのスタンドアロン0x80バイトとして)と一致しません一致しません.)、長さは30 + 1 + 30 + 1 + 2 * 30 = 122、perlまたはmawk、3 * 30 = 90でありgawkます。

バイト単位でカウントする場合は、ロケールをCで修正しますLC_ALL=C grep/awk/sed...

4つのソリューションすべてで、上記の行に122文字が含まれていると見なされます。perlGNUツールを除き、NUL文字(0x0バイト)を含む行には潜在的な問題があります。


¹ perl動作はPERL_UNICODE環境変数の影響を受けます


「効率的」とはどういう意味ですか?
rowantran

マナトワークはタイピング効率を意味すると思います。とにかく暗黙のうちにawkドロップすると($0)、近づくことができます;)。
トール

9
ところで、で正規表現を行の先頭に固定すると^、わずかに高速になりますgrep '^.\{80\}' file
cas

4
Perlソリューションは、他のすべてのソリューションとは異なり、UTF-8などの可変サイズエンコーディングを考慮していません。
BatchyX

6
Nの十分に大きな値はgrepでは失敗しますが、awkでは成功します。(たとえば、成功しながら、grep '^.\{1000\}' file戻ります。)grep: invalid repetition count(s)awk 'length>1000' file
mdahlman 14

1

シェルアプローチ:

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

Pythonのアプローチ:

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

または、読みやすくするための短いスクリプトとして:

#!/usr/bin/env python
import sys

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

改行文字\nを計算から除外したい場合は、次のようにすることif len(line) > 79ができますif len(line.strip()) > 79

サイドノート:これはPython 2.7構文です。print()Python 3に使用

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.