UNIXコマンドを使用して、テキストファイルの各行の文字数を出力したいと思います。私はそれがPowerShellで簡単であることを知っています
gc abc.txt | % {$_.length}
しかし、UNIXコマンドが必要です。
回答:
Awkを使用します。
awk '{ print length }' abc.txt
while IFS= read -r line; do echo ${#line}; done < abc.txt
これはPOSIXなので、どこでも機能するはずです。
編集:ウィリアムによって提案されたように-rを追加しました。
編集:Unicodeの処理に注意してください。ロケールが正しく設定されているBashとzshはコードポイントの数を表示しますが、dashはバイトを表示するため、シェルの機能を確認する必要があります。そして、とにかくUnicodeには他にも多くの可能な長さの定義があるので、実際に何が必要かによって異なります。
編集:IFS=
先頭と末尾のスペースが失われないように接頭辞を付けます。
IFS=
は、必ずread
コマンドに設定してください。だからIFS= read -r
。read
を使用IFS
して単語分割を行い、分割されたすべての単語が1つの使用可能な変数(line
)に貼り付けられたとしても、元のすべての区切り文字または1つの潜在的に異なる文字と一緒に貼り付けられる保証はありません。もの。たとえば、デフォルトのIFSを使用すると、行foo bar
がになりfoo bar
、7つのスペースが失われる可能性があります。(Stack Overflowがこのコメントの文字列の例で隣接するスペースを失ったように)。
IFS
設定する必要がありますが、そうでない場合の問題はもっと微妙です。
上記の他の回答を試しましたが、大きなファイルを処理する場合、特に1行のサイズが使用可能なRAMの約1/4を超えると、適切な解決策にはほど遠いものになります。
この問題では必要ありませんが、bashとawkの両方が行全体を丸呑みします。十分なメモリがある場合でも、行が長すぎるとBashはエラーになります。
私は非常に単純で、かなり最適化されていないpythonスクリプトを実装しました。これは、大きなファイル(1行あたり最大4 GB)でテストした場合、丸呑みせず、与えられたものよりもはるかに優れたソリューションです。
これが本番環境でタイムクリティカルなコードである場合は、これが実際にボトルネックであることをテストした後、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
これを試して:
while read line
do
echo -e |wc -m
done <abc.txt
echo -e | wc -m
しましたね。コマンドの無駄な使用です。シェルは変数内の文字を数えることができます。Plusecho -e
は完全に互換性がなく、シェルの半分で機能しますが、いくつかのエスケープシーケンスで開始すると、他のいくつかでは機能し、残りは何も機能しません。