Bash:计算几个按字母顺序排列的文件中的 N 个字符

Bash:计算几个按字母顺序排列的文件中的 N 个字符

我与一位校对员合作,我为每 N 个字符支付一定的费用(例如 500000)。他(通常)按字母顺序创建/编辑文件。内容/文件名采用(非拉丁)utf-8。简单的纯文本 Markdown (.md) 或 org (.org) 文件。

我需要找到一种有效的方法来为自己记下他的“N 个字符里程碑”,以便我知道何时向他付款。举个例子,假设我上次付钱给他,直到文件“aab.md”中的字符号 3036。他完成了该文件,继续处理“aac.md”、“aad.md”,现在位于“csdw.md”上。

  1. 我如何“测量”该流中的 N 个字符(包括所有内容:标点符号、空格、数字、换行符、大括号等)(假设所有字符都位于同一目录中)?即,我需要一个 bash 命令,它将获取“aab.md”、3036 和 N 作为输入,并提供类似以下内容的内容:“csaw.md”、5023(意味着 N 个字符在该文件中以该字母结尾)。
  2. 如何列出上一个命令中所包含的文件?
  3. 这不太重要,但如果可能的话 - 如果文件分布在多个目录中(也是按字母顺序排列),那么 #1 中的命令会是什么样子,就像他上次停在文件“a/aab.txt”中的字符 3036 上一样。 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。例如é,写为U+0065U+03011 个字素簇,用 2 个字符(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[@]/#/.\/}"。 (我们添加前缀以避免以或 、、 、 空格开头./的文件名出现问题...-|<>

相关内容