ファイル内のすべてのN文字を読み取る最速の方法は何ですか?

ファイル内のすべてのN文字を読み取る最速の方法は何ですか?

私はBashでN文字ごとにファイルを読み取るためのいくつかの方法をすでに知っています。

LC_ALL=C
while read -n100 character; do
    echo "$character"
done < <(cat "$@" | tr -d '\n')
    echo "$character

しかし、これが動作している間、Bashまたはposix / unixツールを使用してこれを行うより速い方法を知りたいです。

これをすばやく行う方法はありますか?

答え1

コピーAdminBeeの結果少し簡単なコードを使用してください。

入力データは対応するデータと同じです。

12345678901234
567890123
4567890123456789012
34567890123

10から始めて10文字ごとに:

$ fold -w 1 file | awk 'NR % 10 == 0'
0
0
0
0
0

同じですが、1から始まります。

$ fold -w 1 file | awk 'NR % 10 == 1'
1
1
1
1
1
1

同じですが、2から始まります。

$ fold -w 1 file | awk 'NR % 10 == 2'
2
2
2
2
2
2

パフォーマンスの面では、これはawkAdminBeeのソリューションと似ていますが、大きな入力(「大きな入力」==上記のテストデータが複数回繰り返される)では少し高速です。

fold -w 1入力の各文字に対して1行を生成し、改行を削除します。使用される両方のコマンドは標準のPOSIXユーティリティです。

答え2

「null フィールド区切り文字」拡張のおかげで、すべての実装ではawkなく、多くの実装で動作するこのソリューションを試してください。awk

awk -F "" -v l=100 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==0) {print $i; last=i}};\
                     if (last) {carry=NF-last} else {carry+=(NF-l)}}' inputfile.txt

これは各文字を単一のフィールド(-F "")として扱い、フィールド番号モジュールで「スキップ長さ」l(あなたの場合は100)がゼロのフィールドのみを印刷し、繰り越しを考慮しますが、改行は無視します。

1から世紀が始まるので、最初の文字はいいえ読む。あなたはそれを使用することができます

awk -F "" -v l=10 -v ofs=1 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==ofs) {print $i; last=i}};\
                             if (last) {carry=NF-last+ofs} else {carry+=(NF-l)}}' inputfile.txt

オフセットを調整してofs

テストケース

Linuxシステムではgawk、およびを使用してmawkテストされました。nawk

  • 入力ファイル
    12345678901234
    567890123
    4567890123456789012
    34567890123
    
  • 「10番目の文字から10ごとに」出力
    $ awk -F "" -v l=10 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==0) {print $i; last=i}}; if (last) {carry=NF-last} else {carry+=(NF-l)}}' testfile.txt 
    0
    0
    0
    0
    0
    
  • 「最初の文字から始めて10ごとに」を出力します。
    $ awk -F "" -v l=10 -v ofs=1 '{last=0; for (i=1;i<=NF;i++) {if ((i+carry)%l==ofs) {print $i; last=i}}; if (last) {carry=NF-last+ofs} else {carry+=(NF-l)}}' testfile.txt 
    1
    1
    1
    1
    1
    1
    

関連情報