我是 Unix 世界的新手,我的文本文件包含 1200 页,由^L
.有没有一种有效的方法可以将该文件分解为两个单独的文件,每个文件有 500 页,然后是第三个文件,其中包含剩余的页面。
我正在考虑读取文件以找到第一个文件,^L
然后将下一个 500 个输出计数到临时文件,继续读取以创建下一个临时文件,或者是否有更有效的方法?
我的脚本是在bash运行中编写的MKS工具包。
答案1
^L
假设每个页面都以(文字)开头Ctrl+L:
awk '/^L/ { p++ } (p-1) % 500 == 0 { f = FILENAME "-page-" p ".txt" } { print > f }' file.txt
这将计算行数^L
,如果计数减 1 是 500 的因数(第 1 页、第 501 页、第 1001 页等),它将将该变量设置f
为文件名以将以下文本输出到其中。
^L
代码中的内容awk
是不是两个字符^
和L
,但是一个文字Ctrl+L(您可以使用 键入Ctrl+VCtrl+L)。您也可以使用\014
它来代替它。
对于一个小测试文档test.txt
:
^L
page 1
^L
page 2
^L
page 3
^L
page 4
...并将 500 更改为 2 进行测试,这会生成两个文件 和test.txt-page-1.txt
,test.txt-page-3.txt
每个文件包含输入文件中的两行(页面标记和文本)。
test.txt-page-1.txt
:
^L
page 1
^L
page 2
test.txt-page-3.txt
:
^L
page 3
^L
page 4
要解析的文件显然在第一页标记之前有一个标题。需要忽略该标头。上述命令的以下变体awk
可以实现此目的:
awk '/^L/ { p++ } (p-1) % 500 == 0 { f = FILENAME "-page-" p ".txt" } p > 0 { print > f }' file.txt
通过将输出限制为p
大于零,我们要求在输出任何内容之前至少解析一个页面标记。
答案2
这是另一种选择。这个锚定在^L字符上(我假设它是单个字符,八进制014
而不是两个文字^和L)。对于您的源数据文件,original.txt
它会将每个页面拆分为自己的文件。从那里您可以将它们连接成所需的块:
# GNU csplit
csplit --prefix='page_' --digits=4 original.txt $'/\014/+1' '{*}'
# MKS csplit
csplit -f 'page_' -n 4 -k original.txt $'/\014/+1' '{9999}'
# Concatenate the required sets of pages together
cat page_{0000..0499} > part_1.txt
cat page_{0500..0999} > part_2.txt
cat page_{1000..9999} > part_3.txt
# Tidy up
rm page_????
答案3
如果可以使用旧的 gnu split:
split -t '^L' -l 500 bigFile part_
-t '^L'
- 单位分隔符是^L分成500个单位的文件
在 bash 中,要介绍^L我们必须输入^V ^L.也可以使用八进制表示法:
split -t $'\014' ...
答案4
这是文本文件还是更复杂的文件(PDF、WORD 等)?也许您应该尝试一下内置split
命令。它的工作原理是这样的
split -l1000 textfile
这会将您的文本文件拆分为多个文件,每个文件包含 1000 行。