将文本文件限制在一定的词长度内,但保持完整的句子

我有一组文本文件需要复制,但希望每个文件的词长度大致相同,同时保持完整的句子。将{.?!}内的任何标点符号视为句子边界是可以接受的。我可以用Python来做这件事,但我正在尝试学习bash,所以欢迎提供建议。我考虑的方法是将目标词长度超出几个词,然后将结果修剪到最后的句子边界。

我熟悉headwc,但我想不出如何将两者结合使用。headman文件没有说明如何使用词数,而wcman文件没有说明如何分割文件。

背景:我正在进行一个使用机器学习的文本分类任务(记录在案,我使用的是weka)。我想确保文本长度(在我的数据中变化很大)不会过多地影响结果。为此,我试图在进行特征提取之前规范化我的文本长度。


回答:

让我们考虑这个测试文件:

$ cat fileDo I exist? I program. Therefore, I am!

假设我们想将这个文件截断为完整的句子,每个句子不超过20个字符:

$ awk -v n=20 -v RS='[.?!]' '{if (length(s $0 RT)>n) exit; else s=s $0 RT;} END{print s;}' fileDo I exist?

如果我们想要不超过30个字符:

$ awk -v n=30 -v RS='[.?!]' '{if (length(s $0 RT)>n) exit; else s=s $0 RT;} END{print s;}' fileDo I exist? I program.

工作原理

  • -v n=20

    这将awk变量n设置为我们想要的最大长度(不包括文件的最后一个换行符)。

  • -v RS='[.?!]'

    这将awk的记录分隔符RS设置为您提到的三个字符中的任何一个。

  • if (length(s $0 RT)>n) exit; else s=s $0 RT

    对于文件中的每个记录(一个记录是一个句子),我们测试将它添加到s是否会使输出过长。如果输出过长,我们就退出。如果没有,我们就将它添加到s中。

    在awk中,$0代表完整的记录,RT是awk在记录末尾找到的记录分隔符。

  • END{print s;}

    在退出之前,这会打印字符串s

替代方案1:基于词数截断

假设我们想基于词数进行截断。例如,如果我们想要6个词:

$ awk -v n=6 -v RS='[[:space:]]+' 'NR>n{exit;} {printf "%s%s",$0,RT;} END{print"";}' fileDo I exist? I program. Therefore, 

不同之处在于我们现在使用空白作为记录分隔符。这样,每个记录就是一个词,我们会一直打印词直到达到限制。

替代方案2:完整句子但限制词数

$ awk -v n=6 -v RS='[.?!]' '{c+=NF; if (c>n) exit; else s=s $0 RT;} END{print s;}' fileDo I exist? I program.

Mac OSX

上述设置记录分隔符RS为正则表达式。这可能需要GNU awk(gawk)。OSX的awk手册页没有说明是否支持此功能。然而,@***报告说,在从macports安装gawk后,上述代码可以在OSX上成功运行。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注