web-dev-qa-db-ja.com

テキストファイルの各行の文字数を印刷する方法

UNIXコマンドを使用して、テキストファイルの各行の文字数を出力したいと思います。私はそれがpowershellで簡単であることを知っています

gc abc.txt | % {$_.length}

しかし、私はUNIXコマンドが必要です。

61
vikas368

Awkを使用します。

awk '{ print length }' abc.txt
120
Fred Foo
while read -r line; do echo ${#line}; done < abc.txt

これはPOSIXなので、どこでも動作するはずです。

編集:ウィリアムが示唆するように-rを追加しました。

編集:Unicode処理に注意してください。ロケールが正しく設定されているBashとzshは、コードポイントの数を表示しますが、ダッシュはバイトを表示するため、シェルの動作を確認する必要があります。そして、とにかくUnicodeには長さの他の多くの可能な定義があるので、それはあなたが実際に望むものに依存します。

13
Jan Hudec

xargsを使用した例を次に示します。

$ xargs -d '\n' -I% sh -c 'echo % | wc -c' < file
2
kenorb

上記の他の回答を試してみましたが、大きなファイルを処理する場合、特に単一行のサイズが使用可能なRAMの〜1/4を超える場合、それらはまともな解決策とはほど遠いです。

Bashとawkの両方は、この問題のために必要ではないが、行全体を丸lurみします。十分なメモリがある場合でも、行が長すぎるとBashはエラーになります。

私は非常にシンプルでかなり最適化されていないpythonスクリプトを実装しました。これは大きなファイル(1行あたり最大4 GB)でテストしてもSlurpされず、与えられたものよりもはるかに優れたソリューションです。

これが本番環境でタイムクリティカルなコードである場合、これが実際にボトルネックであることをテストした後、Cでアイデアを書き直すか、(一度に1バイトだけを読み取るのではなく)読み取り呼び出しでより良い最適化を実行できます。

コードでは、改行は改行文字であると想定しています。これは、Unixでは適切な想定ですが、Mac OS/WindowsではYMMVです。最後の行の文字カウントが見落とされないように、ファイルが改行で終わっていることを確認してください。

from sys import stdin, exit

counter = 0
while True:
    byte = stdin.buffer.read(1)
    counter += 1
    if not byte:
        exit()
    if byte == b'\x0a':
        print(counter-1)
        counter = 0
2
user2875414

これを試して:

while read line    
do    
    echo -e |wc -m      
done <abc.txt    
0
Rahul