【问题标题】:splitting file to smaller max n-chars files without cutting any line将文件拆分为更小的最大 n-chars 文件而不剪切任何行
【发布时间】:2023-03-31 05:30:02
【问题描述】:

以下是使用 cal 命令生成的示例输入文本文件:

$ cal 2743 > sample_text

在这个例子中这个文件有 2180 个字符

$ wc sample_text
  36  462 2180 sample_text

我想将其拆分为较小的文件,每个文件不超过 700 行,但保留完整状态的行(不能剪切任何行)

我可以使用以下 awk 代码查看每个这样的块:

$ awk '{l=length+l;if(l<=700){print l,$0}else{l=length;print "\nnext block\n",l,$0}}' sample_text
32                             2743
98       January               February               March
164 Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
230                 1  2      1  2  3  4  5  6      1  2  3  4  5  6
296  3  4  5  6  7  8  9   7  8  9 10 11 12 13   7  8  9 10 11 12 13
362 10 11 12 13 14 15 16  14 15 16 17 18 19 20  14 15 16 17 18 19 20
428 17 18 19 20 21 22 23  21 22 23 24 25 26 27  21 22 23 24 25 26 27
494 24 25 26 27 28 29 30  28                    28 29 30 31
560 31
560
626        April                  May                   June
692 Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa

next block
 66              1  2  3                     1         1  2  3  4  5
132  4  5  6  7  8  9 10   2  3  4  5  6  7  8   6  7  8  9 10 11 12
198 11 12 13 14 15 16 17   9 10 11 12 13 14 15  13 14 15 16 17 18 19
264 18 19 20 21 22 23 24  16 17 18 19 20 21 22  20 21 22 23 24 25 26
330 25 26 27 28 29 30     23 24 25 26 27 28 29  27 28 29 30
396                       30 31
396
462         July                 August              September
528 Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
594              1  2  3   1  2  3  4  5  6  7            1  2  3  4
660  4  5  6  7  8  9 10   8  9 10 11 12 13 14   5  6  7  8  9 10 11

next block
 66 11 12 13 14 15 16 17  15 16 17 18 19 20 21  12 13 14 15 16 17 18
132 18 19 20 21 22 23 24  22 23 24 25 26 27 28  19 20 21 22 23 24 25
198 25 26 27 28 29 30 31  29 30 31              26 27 28 29 30
264
264
330       October               November              December
396 Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
462                 1  2      1  2  3  4  5  6            1  2  3  4
528  3  4  5  6  7  8  9   7  8  9 10 11 12 13   5  6  7  8  9 10 11
594 10 11 12 13 14 15 16  14 15 16 17 18 19 20  12 13 14 15 16 17 18
660 17 18 19 20 21 22 23  21 22 23 24 25 26 27  19 20 21 22 23 24 25

next block
 66 24 25 26 27 28 29 30  28 29 30              26 27 28 29 30 31
132 31

我有问题将每个最多 700 个字符的块保存到单独的文件中 - 使用以下命令它只生成一个 file.0,并且预期是拆分文件 file.0、file.1、file.2 和 file.3这个输入示例

$ awk 'c=0;{l=length+l;if(l<=700){print>"file."c}else{c=c++;l=length;print>"file."c}}' sample_text
$ cksum *
3868619974 2180 file.0
3868619974 2180 sample_text

【问题讨论】:

  • 如果一行本身大于您的字节数限制会怎样?
  • 除此之外,您可以逐行循环,保留当前文件中的字节数,如果合适则附加它(即,它的长度加上当前计数低于限制)或创建一个如果没有,则新的。
  • 当你说no more than 700 lines ITYM no more than 700 charactersprint&gt;"file."c 是非 POSIX(输入或输出重定向右侧的非括号表达式),因此在某些 awks 中会失败。同样,在大多数 awk 中,一旦超过十几个,不关闭输出文件就会因打开文件过多而失败。
  • 永远不要将变量命名为l,因为它看起来太像数字1,所以会混淆你的代码。我盯着l=length+l 看了几分钟,试图弄清楚你为什么将1 添加到length() (例如,如果它是为了打印换行符或空行,或者你到底在做什么) ) 在我意识到那是字母 l 而不是数字 1 之前。

标签: shell awk


【解决方案1】:

应该这样做:

BEGIN {
    maxChars = 700
    out = "file.0"
}
{
    numChars = length($0)
    totChars += numChars
    if ( totChars > maxChars ) {
        close(out)
        out = "file." ++cnt
        totChars = numChars
    }
    print > out
}

【讨论】:

    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多