Bash:複数のアルファベットファイルからN文字を計算する

Bash:複数のアルファベットファイルからN文字を計算する

私はN字ごとに特定の手数料(例:500,000)を支払う校正者と協力しています。彼は(通常)アルファベット順にファイルを作成/編集します。コンテンツ/ファイル名はラテン語ではなくUTF-8です。単純なプレーンテキストMarkdown(.md)またはorg(.org)ファイル。

私は彼にいつ支払うべきかを知るために彼の「N文字マイルストーン」を直接記録する効率的な方法を見つけなければなりません。たとえば、私が前回「aab.md」ファイルの文字記号3036まで彼にお金を払ったとしましょう。彼はファイルを完成させ、「aac.md」、「aad.md」に移動し、現在は「csdw.md」にあります。

  1. このストリームでは、N文字(句読点、スペース、数字、改行、中括弧などのすべての項目を含む)をどのように「測定」しますか(すべての文字が同じディレクトリにあると仮定)。つまり、「aab.md」、3036、およびNを入力として使用し、「csaw.md」、5023(対応するファイルに文字の終わりで始まるN文字があることを意味します)を提供するbashコマンドが必要です。
  2. 前のコマンドに含まれているファイルを一覧表示するには?
  3. これはそれほど重要ではありませんが、可能であれば、ファイルが "a/aab.txt" 文字ファイルで最後に停止されたように、ファイルが複数のディレクトリ(アルファベット順)に分散されている場合、#1のコマンドはどのように見えますか?上記と同じです。 md"で、今"np/csdw.md"にありますか?

cat * | wc -m私はそれが私にすべてのファイルの文字数を提供することを知っていましたが、私が必要とするものからは遠いです。

答え1

zsh代わりに使用することをお勧めしますbash。その後、新しいファイルのソートされた再帰的なリストを取得する方が簡単ですaab.md

#! /bin/zsh -
last_file=aab.md offset_in_last_file=3036 n=500000
new_files=(**/*.(md|org)(N))
new_files=($new_files[(Re)$last_file,-1])

(($#new_files)) && perl -Ci -sne '
   $l = length; $go += $l; $o += $l;
   if ($go >= $n) {
     printf qq(file="%s", line=%d, char-offset=%d\n), $ARGV, $., $o + $n - $go;
     exit;
   }
   $o = 0 if eof' -- -go=-$offset_in_last_file -n=$n ./$^new_files

文字数ではなく文字数クラスタの数を$l = length置き換えます$l = () = /\X/g。たとえば、1つの子クラスタéで書くとU+0065U+03012文字(UTF-8では3バイト)で表され、U + 00E9で書くと1文字クラスタと1文字(2バイト)で表されます。

bash 4.4+とGNUを使用すると、awk次の操作を実行して$new_files配列を構成できます。

shopt -s nullglob extglob globstar
readarray -td '' new_files < <(
    printf '%s\0' **/*.@(md|org) |
      L=$last_file awk -v RS='\0' -v ORS='\0' '$0 == ENVIRON["L"], 0'
  )

の場合にもbash変更しなければなりません。 (または、、、、、スペースで始まるファイル名に関連する問題を回避するためにプレフィックスを追加します..../$^new_files"${new_files[@]/#/.\/}"./-|<>

関連情報