【问题标题】:How can I split a text based on every n.th words?如何根据每个第 n 个单词拆分文本?
【发布时间】:2020-07-24 14:18:43
【问题描述】:

我正在尝试为每 1000 个单词拆分一个文本文件。

awk -v RS='[[:space:]]+' 'END{print NR+0}' filename

使用 awk 我可以计算文件中的单词,但我不知道如何拆分它。

最终输出=文件名(1).txt、文件名(2).txt

【问题讨论】:

  • 欢迎。你说的词到底是什么意思?这比看起来要复杂得多。如果每一行都有一个单词,那awk会说单词数只有1!
  • 每一行是否只包含一个单词?如果不是,您是否要保留某些单词在同一行的事实?
  • 如果每行一个字,就用split,而不是awk
  • 不,每行不止一个字。

标签: unix awk


【解决方案1】:

这个完全病态的解决方案应该适用于少于 10000 字的文件:

. <(echo -e 'uno due tre\nquattro\ncinque sei sette otto\nnove dieci undici dodici tredici' | sed -zE '
s/^/\x0/
:a
y/012345678/123456789/
s/\x0(([^ \n]+[ \n]+){4})/cat > file0 <<EOF\n\1\nEOF\n\x0/
ta
s/\x0(.*)/cat > file0 <<EOF\n\1\nEOF\n\x0/
s/\n+/\n/g')

本质上,它在必须发生拆分的点上散布一些代码,使得输出文件是bash 脚本,它是从 heredocumentcat 命令序列/em> 并写入一个文件(最多允许 10 个文件!)。此脚本来源(. file 只是 source file,只是更丑)。您可以通过删除前导 . &lt;( 和尾随 ) 来查看脚本。

好处是它在必要时在行的中间分割大文件,而不改变没有发生分割的行。

最难看的是文件倒序编号。

字数的限制是因为我只在文件名上实现了一位数的加法;可以通过以与 herehere 类似的方式实现添加来删除它。

【讨论】:

    【解决方案2】:

    您可以使用awk 轻松完成此操作。如果您编写一个函数来实际处理将单词从数组输出到文件,它有助于保持混乱。保留一个计数器来对输出文件名进行编号,例如wordsfile_1(前 1000 字)、wordsfile_2(后 1000 字)等等。然后,只需跟踪您添加到数组中的单词数量,并在达到 1000 个单词时调用输出函数。然后删除数组,让它准备好保存接下来的 1000 个单词,重置你的单词计数器并继续。

    例如,您可以执行以下操作:

    awk '
        function writefile() {
            fname="wordsfile_" ++c + 0
            for (j=1; j<=n; j++)
                print a[j] > fname
            delete a
            n = 0
        }
        {
            for (i=1; i<=NF; i++) {
                a[++n] = $i
                if (n == 1000)
                    writefile()
            }
        }
    END {
        writefile()
    }' input_file
    

    function writefile() 处理将输出写入 1000 字文件并删除数组并重置计数器 n。 END 规则只是再次调用该函数以输出自上次输出以来收集的所有单词。

    如果您还有其他问题,请告诉我。

    【讨论】:

    • 它的魅力:) 我们可以保持文件的一致性吗?我们可以按位置打印单词而不是一行中的一个单词吗?
    • 我们可以修改它,使它可以在单词的旁边或之前打印行号,以便我们可以获取行号? .例如:“Lorem 220 ipsum 221 dolor 221”.awk 'NR == 1000' wordsfile_1 | awk -F'[^0-9]*' '$0=$2' 然后,我们可以在这里使用结果: awk 'NR >= 1 && NR filename_1.我想,我可以把它放在一个 for 循环中,它可以生成文件。
    • 当然,您可以为看到的单词总数添加另一个计数器,然后在写入文件的单词之前写入该输出。如果您使用total 作为计数器,那么只需写printf "%4d %s\n", total, a[j] &gt; fname(使用printf 将允许您设置数字的字段宽度)
    【解决方案3】:
    #!/bin/bash
    for FILE in *.txt
    do
    #FILE="FILENAME.txt" 
    read -p "HOW MANY WORDS SHOULD BE IN YOUR FILES? (~ APPROXIMATE) " BUFFER
    #BUFFER=1000 # APPROXIMATE NUMBER OF WORDS IN A FILE 
    
    NW=$(wc -w $FILE | awk '{print $1}') #NW=NUMBER OF WORDS IN YOUR FILE
    
    if [[ $NW -gt $BUFFER ]]
    then
    
    LINENUMBER=$(wc -l $FILE | awk '{print $1}')
    WCOUNT=0
    FL=1 #FIRST LINE NUMBER OF EVERY NEW FILE
    FN=1 #FILE NUMBER
    
    for j in $(eval echo "{1..$LINENUMBER}")
    do
        INC=$(sed -n "${j}p" $FILE | wc -w)
        WCOUNT=$(( WCOUNT + INC ))
        if [[ $WCOUNT -gt $BUFFER ]];
        then
            sed -n "${FL},${j}p" $FILE >  ${FILE%%.*}_${FN}.txt
            FL=$(( j + 1))
            (( FN++ ))
            WCOUNT=0
        fi
    done
    sed -n "${FL},\$p" $FILE >  ${FILE%%.*}_${FN}.txt
    fi 
    done
    

    我找到了一个不同的解决方案,它生成的文件大约有 1000 个单词。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      • 2013-04-20
      • 2015-01-12
      • 1970-01-01
      • 2019-11-01
      相关资源
      最近更新 更多