根据bash中的单词数拆分文本文件

时间:2016-05-12 02:12:53

标签: bash awk sed

我知道要从我可以执行的文件中提取行的子集:

sed -n 2208202,2218201p file >>new

bash中有没有办法根据单词提取文件的子集(保留确切的顺序)?例如,提取文件的前10k个单词,或10000到20000的单词?

3 个答案:

答案 0 :(得分:3)

将此作为测试文件:

$ cat file
one two
three four five
six seven
eight nine
ten eleven twelve
thirteen
fourteen

使用GNU awkgawk),让我们选择单词4到10:

$ awk -v RS='[[:space:]]+' '4<=NR && NR<=10{ printf "%s%s",$0,RT } END{print""}' file
four five
six seven
eight nine
ten 

请注意,这会保留原始文件的空格和换行符。

如何运作

  • -v RS='[[:space:]]+'

    这会将awk的记录分隔符设置为任何空格组合。

  • 4<=NR && NR<=10{ printf "%s%s",$0,RT }

    对于记录4到10,这将打印记录,其中包含输入文件中的任何空格。 RT不是POSIX。

  • END{print""}

    如果最后一个单词不是一行中的最后一个单词,则会打印最终换行符。

答案 1 :(得分:1)

假设:

  • 您将 word 定义为任何非空白字符的运行
  • 您使用 GNU Awk或Mawk

尝试:

awk -v from=10000 -v to=20000 -v RS='[[:space:]]+' 'NR < from {next} NR > to {exit} 1' file

- 只需省略-v from=...即可以第一个字开头 - 此解决方案在输出上打印每个单词;相反,如果您想保留单词之间的原始空格,请参阅John1024's helpful answer

  • RS='[[:space:]]+'将输入记录分隔符(RS)定义为任何空格运行,这有效地使每个非空白字符的运行成为自己的记录。

    • 使用多字符 RS值可使此解决方案符合非POSIX标准;同样在OS X上使用的BSD awk仍然接近POSIX规范。因此不支持这样的RS值。
  • 只要基于1的记录索引NR < from {next}低于范围的起始索引,
  • NR就会跳过输入记录。

  • 一旦记录索引超出范围的结束索引,
  • NR > to {exit} 就会完全退出。这可能是一个包含大量输入文件的重要优化。

  • 1{ print }的常用简写,在各自的行上打印,因为print打印每个输入记录,然后是值ORS,即输出记录分隔符,默认为\n

  • 警告:第一个单词前面前面的空格报告为字(记录)。

答案 2 :(得分:1)

awk救援!

这也适用于其他问题

$ awk -v n=15 'sum<n && p{print p} 
                         {p=$0; sum+=NF} 
                   sum>=n{exit} 
                      END{for(i=1;i<=n-sum+NF;i++) printf "%s ", $i; 
                          print ""}' file.txt

这是第一个n字脚本。范围可以类似地实现。