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

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

ファイル内で 79 文字を超える行を見つけることは可能ですか?

答え1

私のテストによると、速度が遅い順に並べると(UTF-8 ロケールの GNU システム上、ASCII 入力の場合):

grep '.\{80\}' file

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

awk 'length>79' file

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

perl¹ のもの(またはマルチバイト文字をサポートしていないawk/ grep/sed実装(またはbusyboxなど))を除いてmawk、長さは文字数でカウントされます。文字LC_CTYPE(ロケールの設定に応じて)バイト

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

たとえば、UTF-8 ロケールで 30 個aの 0x80 バイト、30b個の 0x81 バイト、および 30 個の UTF-8個 (0xc3 0xa9 としてエンコード) で構成される行は、 GNU /とé一致しません(スタンドアロンの 0x80 バイトは と一致しないため)。またはでは長さが 30+1+30+1+2*30=122 になり、 では 3*30=90 になります。.\{80\}grepsed.perlmawkgawk

バイト単位でカウントしたい場合は、ロケールを に固定しCますLC_ALL=C grep/awk/sed...

これにより、4 つのソリューションすべてで、上記の行に 122 文字が含まれていることが考慮されるようになります。 および GNU ツールを除きperl、NUL 文字 (0x0 バイト) を含む行では依然として問題が発生する可能性があります。


¹ただし、perl動作は環境変数によって影響を受ける可能性がありますPERL_UNICODE

答え2

シェルアプローチ:

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の構文です。Python print()3で使用してください。

関連情報